00001
00002
00003
00004 #include "ace/Process_Manager.h"
00005
00006 #if !defined (__ACE_INLINE__)
00007 #include "ace/Process_Manager.inl"
00008 #endif
00009
00010 #include "ace/ACE.h"
00011 #include "ace/Guard_T.h"
00012 #include "ace/Process.h"
00013 #include "ace/Signal.h"
00014 #include "ace/Object_Manager.h"
00015 #include "ace/Log_Msg.h"
00016 #include "ace/Reactor.h"
00017 #include "ace/Countdown_Time.h"
00018 #include "ace/OS_NS_sys_wait.h"
00019 #include "ace/OS_NS_signal.h"
00020 #include "ace/OS_NS_unistd.h"
00021 #include "ace/OS_NS_sys_time.h"
00022
00023 ACE_RCSID (ace,
00024 Process_Manager,
00025 "Process_Manager.cpp,v 4.98 2006/06/01 09:16:38 jwillemsen Exp")
00026
00027 #if defined (ACE_HAS_SIG_C_FUNC)
00028 extern "C" void
00029 ACE_Process_Manager_cleanup (void *instance, void *arg)
00030 {
00031 ACE_Process_Manager::cleanup (instance, arg);
00032 }
00033 #endif
00034
00035 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00036
00037 void
00038 ACE_Process_Manager::cleanup (void *, void *)
00039 {
00040 ACE_Process_Manager::close_singleton ();
00041 }
00042
00043
00044
00045
00046 #if !defined (ACE_WIN32) && !defined (ACE_LACKS_UNIX_SIGNALS)
00047 static void
00048 sigchld_nop (int, siginfo_t *, ucontext_t *)
00049 {
00050 return;
00051 }
00052 #endif
00053
00054
00055 ACE_ALLOC_HOOK_DEFINE(ACE_Process_Manager)
00056
00057
00058 ACE_Process_Manager *ACE_Process_Manager::instance_ = 0;
00059
00060
00061
00062 int ACE_Process_Manager::delete_instance_ = 0;
00063
00064 ACE_Process_Descriptor::~ACE_Process_Descriptor (void)
00065 {
00066 }
00067
00068 void
00069 ACE_Process_Descriptor::dump (void) const
00070 {
00071 #if defined (ACE_HAS_DUMP)
00072 ACE_TRACE ("ACE_Process_Descriptor::dump");
00073
00074 ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00075
00076 ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\nproc_id_ = %d"),
00077 this->process_->getpid( )));
00078
00079 ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00080 #endif
00081 }
00082
00083 void
00084 ACE_Process_Manager::dump (void) const
00085 {
00086 #if defined (ACE_HAS_DUMP)
00087 ACE_TRACE ("ACE_Process_Manager::dump");
00088
00089 ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00090
00091 ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\nmax_process_table_size_ = %d"), this->max_process_table_size_));
00092 ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\ncurrent_count_ = %d"), this->current_count_));
00093
00094 for (size_t i = 0; i < this->current_count_; i++)
00095 this->process_table_[i].dump ();
00096
00097 ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00098 #endif
00099 }
00100
00101 ACE_Process_Descriptor::ACE_Process_Descriptor (void)
00102 : process_ (0),
00103 exit_notify_ (0)
00104 {
00105 ACE_TRACE ("ACE_Process_Descriptor::ACE_Process_Descriptor");
00106 }
00107
00108 ACE_Process_Manager *
00109 ACE_Process_Manager::instance (void)
00110 {
00111 ACE_TRACE ("ACE_Process_Manager::instance");
00112
00113 if (ACE_Process_Manager::instance_ == 0)
00114 {
00115
00116 ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon,
00117 *ACE_Static_Object_Lock::instance (), 0));
00118
00119 if (ACE_Process_Manager::instance_ == 0)
00120 {
00121 ACE_NEW_RETURN (ACE_Process_Manager::instance_,
00122 ACE_Process_Manager,
00123 0);
00124 ACE_Process_Manager::delete_instance_ = 1;
00125
00126
00127
00128
00129
00130 #if defined ACE_HAS_SIG_C_FUNC
00131 ACE_Object_Manager::at_exit (ACE_Process_Manager::instance_,
00132 ACE_Process_Manager_cleanup,
00133 0);
00134 #else
00135 ACE_Object_Manager::at_exit (ACE_Process_Manager::instance_,
00136 ACE_Process_Manager::cleanup,
00137 0);
00138 #endif
00139
00140 }
00141 }
00142
00143 return ACE_Process_Manager::instance_;
00144 }
00145
00146 ACE_Process_Manager *
00147 ACE_Process_Manager::instance (ACE_Process_Manager *tm)
00148 {
00149 ACE_TRACE ("ACE_Process_Manager::instance");
00150 ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon,
00151 *ACE_Static_Object_Lock::instance (), 0));
00152
00153 ACE_Process_Manager *t = ACE_Process_Manager::instance_;
00154
00155 ACE_Process_Manager::delete_instance_ = 0;
00156
00157
00158
00159
00160
00161 #if defined ACE_HAS_SIG_C_FUNC
00162 ACE_Object_Manager::at_exit (ACE_Process_Manager::instance_,
00163 ACE_Process_Manager_cleanup,
00164 0);
00165 #else
00166 ACE_Object_Manager::at_exit (ACE_Process_Manager::instance_,
00167 ACE_Process_Manager::cleanup,
00168 0);
00169 #endif
00170
00171 ACE_Process_Manager::instance_ = tm;
00172 return t;
00173 }
00174
00175 void
00176 ACE_Process_Manager::close_singleton( void )
00177 {
00178 ACE_TRACE ("ACE_Process_Manager::close_singleton");
00179
00180 ACE_MT (ACE_GUARD (ACE_Recursive_Thread_Mutex, ace_mon,
00181 *ACE_Static_Object_Lock::instance ()));
00182
00183 if (ACE_Process_Manager::delete_instance_)
00184 {
00185 delete ACE_Process_Manager::instance_;
00186 ACE_Process_Manager::instance_ = 0;
00187 ACE_Process_Manager::delete_instance_ = 0;
00188 }
00189 }
00190
00191 int
00192 ACE_Process_Manager::resize (size_t size)
00193 {
00194 ACE_TRACE ("ACE_Process_Manager::resize");
00195
00196 if (size <= this->max_process_table_size_)
00197 return 0;
00198
00199 ACE_Process_Descriptor *temp = 0;
00200
00201 ACE_NEW_RETURN (temp,
00202 ACE_Process_Descriptor[size],
00203 -1);
00204
00205 for (size_t i = 0;
00206 i < this->current_count_;
00207 i++)
00208
00209 temp[i] = this->process_table_[i];
00210
00211 this->max_process_table_size_ = size;
00212
00213 delete [] this->process_table_;
00214
00215 this->process_table_ = temp;
00216 return 0;
00217 }
00218
00219
00220
00221 int
00222 ACE_Process_Manager::open (size_t size,
00223 ACE_Reactor *r)
00224 {
00225 ACE_TRACE ("ACE_Process_Manager::open");
00226
00227 if (r)
00228 {
00229 this->reactor (r);
00230 #if !defined (ACE_WIN32) && !defined (ACE_LACKS_UNIX_SIGNALS)
00231
00232 if (r->register_handler (SIGCHLD, this) == -1)
00233 return -1;
00234 #endif
00235 }
00236
00237 ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->lock_, -1));
00238
00239 if (this->max_process_table_size_ < size)
00240 this->resize (size);
00241 return 0;
00242 }
00243
00244
00245
00246 ACE_Process_Manager::ACE_Process_Manager (size_t size,
00247 ACE_Reactor *r)
00248 : ACE_Event_Handler (),
00249 process_table_ (0),
00250 max_process_table_size_ (0),
00251 current_count_ (0),
00252 default_exit_handler_ (0)
00253 #if defined (ACE_HAS_THREADS)
00254 , lock_ ()
00255 #endif
00256 {
00257 ACE_TRACE ("ACE_Process_Manager::ACE_Process_Manager");
00258
00259 if (this->open (size,
00260 r) == -1)
00261 ACE_ERROR ((LM_ERROR,
00262 ACE_LIB_TEXT ("%p\n"),
00263 ACE_LIB_TEXT ("ACE_Process_Manager")));
00264 }
00265
00266
00267
00268 int
00269 ACE_Process_Manager::close (void)
00270 {
00271 ACE_TRACE ("ACE_Process_Manager::close");
00272
00273 if (this->reactor () != 0)
00274 {
00275 #if !defined (ACE_WIN32) && !defined (ACE_LACKS_UNIX_SIGNALS)
00276 this->reactor ()->remove_handler (SIGCHLD, (ACE_Sig_Action *) 0);
00277 #endif
00278 this->reactor (0);
00279 }
00280
00281 ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->lock_, -1));
00282
00283 if (this->process_table_ != 0)
00284 {
00285 while (this->current_count_ > 0)
00286 this->remove_proc (0);
00287
00288 delete [] this->process_table_;
00289 this->process_table_ = 0;
00290 this->max_process_table_size_ = 0;
00291 this->current_count_ = 0;
00292 }
00293
00294 if (this->default_exit_handler_ != 0)
00295 this->default_exit_handler_->handle_close (ACE_INVALID_HANDLE,0);
00296 this->default_exit_handler_ = 0;
00297
00298 return 0;
00299 }
00300
00301 ACE_Process_Manager::~ACE_Process_Manager (void)
00302 {
00303 ACE_TRACE ("ACE_Process_Manager::~ACE_Process_Manager");
00304 this->close ();
00305 }
00306
00307 #if !defined (ACE_WIN32)
00308
00309
00310
00311
00312
00313
00314
00315 int
00316 ACE_Process_Manager::handle_input (ACE_HANDLE)
00317 {
00318 ACE_TRACE ("ACE_Process_Manager::handle_input");
00319
00320 pid_t pid;
00321
00322 do
00323 pid = this->wait (0,
00324 ACE_Time_Value::zero);
00325 while (pid != 0 && pid != ACE_INVALID_PID);
00326
00327 return 0;
00328 }
00329
00330 #endif
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340 int
00341 ACE_Process_Manager::handle_signal (int,
00342 siginfo_t *si,
00343 ucontext_t *)
00344 {
00345 #if defined (ACE_WIN32)
00346 ACE_HANDLE proc = si->si_handle_;
00347 ACE_exitcode status = 0;
00348 BOOL result = ::GetExitCodeProcess (proc,
00349 &status);
00350 if (result)
00351 {
00352 if (status != STILL_ACTIVE)
00353 {
00354 {
00355 ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, lock_, -1));
00356
00357 ssize_t const i = this->find_proc (proc);
00358 if (i == -1)
00359 return -1;
00360 #if 0
00361 pid_t pid = i != -1
00362 ? process_table_[i].process_->getpid ()
00363 : ACE_INVALID_PID;
00364 #endif
00365 this->notify_proc_handler (i, status);
00366 this->remove_proc (i);
00367 }
00368 return -1;
00369 }
00370 else
00371 ACE_ERROR_RETURN ((LM_ERROR,
00372 ACE_LIB_TEXT ("Process still active")
00373 ACE_LIB_TEXT (" -- shouldn't have been called yet!\n")),
00374 0);
00375 }
00376 else
00377 {
00378
00379 ACE_ERROR_RETURN ((LM_ERROR,
00380 ACE_LIB_TEXT ("GetExitCodeProcess failed")),
00381 -1);
00382 }
00383 #else
00384 ACE_UNUSED_ARG (si);
00385 return reactor ()->notify (this, ACE_Event_Handler::READ_MASK);
00386 #endif
00387 }
00388
00389 int
00390 ACE_Process_Manager::register_handler (ACE_Event_Handler *eh,
00391 pid_t pid)
00392 {
00393 ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->lock_, -1));
00394
00395 if (pid == ACE_INVALID_PID)
00396 {
00397 if (this->default_exit_handler_ != 0)
00398 this->default_exit_handler_->handle_close (ACE_INVALID_HANDLE, 0);
00399 this->default_exit_handler_ = eh;
00400 return 0;
00401 }
00402
00403 ssize_t const i = this->find_proc (pid);
00404
00405 if (i == -1)
00406 {
00407 errno = EINVAL;
00408 return -1;
00409 }
00410
00411 ACE_Process_Descriptor &proc_desc = this->process_table_[i];
00412
00413 if (proc_desc.exit_notify_ != 0)
00414 proc_desc.exit_notify_->handle_close (ACE_INVALID_HANDLE, 0);
00415 proc_desc.exit_notify_ = eh;
00416 return 0;
00417 }
00418
00419
00420
00421 pid_t
00422 ACE_Process_Manager::spawn (ACE_Process_Options &options,
00423 ACE_Event_Handler *event_handler)
00424 {
00425 ACE_Process *process = 0;
00426 ACE_NEW_RETURN (process,
00427 ACE_Managed_Process,
00428 ACE_INVALID_PID);
00429
00430 pid_t const pid = spawn (process, options, event_handler);
00431 if (pid == ACE_INVALID_PID || pid == 0)
00432 delete process;
00433
00434 return pid;
00435 }
00436
00437
00438
00439 pid_t
00440 ACE_Process_Manager::spawn (ACE_Process *process,
00441 ACE_Process_Options &options,
00442 ACE_Event_Handler *event_handler)
00443 {
00444 ACE_TRACE ("ACE_Process_Manager::spawn");
00445
00446 pid_t const pid = process->spawn (options);
00447
00448
00449 if (pid == ACE_INVALID_PID || pid == 0)
00450 return pid;
00451
00452 ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex,
00453 ace_mon, this->lock_, -1));
00454
00455 if (this->append_proc (process, event_handler) == -1)
00456
00457 return ACE_INVALID_PID;
00458
00459 return pid;
00460 }
00461
00462
00463
00464 int
00465 ACE_Process_Manager::spawn_n (size_t n,
00466 ACE_Process_Options &options,
00467 pid_t *child_pids,
00468 ACE_Event_Handler *event_handler)
00469 {
00470 ACE_TRACE ("ACE_Process_Manager::spawn_n");
00471
00472 if (child_pids != 0)
00473 for (size_t i = 0;
00474 i < n;
00475 ++i)
00476 child_pids[i] = ACE_INVALID_PID;
00477
00478 for (size_t i = 0;
00479 i < n;
00480 i++)
00481 {
00482 pid_t const pid = this->spawn (options, event_handler);
00483 if (pid == ACE_INVALID_PID || pid == 0)
00484
00485 return pid;
00486 else if (child_pids != 0)
00487 child_pids[i] = pid;
00488 }
00489
00490 return 0;
00491 }
00492
00493
00494
00495
00496 int
00497 ACE_Process_Manager::append_proc (ACE_Process *proc,
00498 ACE_Event_Handler *event_handler)
00499 {
00500 ACE_TRACE ("ACE_Process_Manager::append_proc");
00501
00502
00503
00504 if (this->current_count_ >= this->max_process_table_size_)
00505 {
00506 size_t new_size = this->max_process_table_size_ * 2;
00507 if (new_size == 0)
00508 new_size = ACE_Process_Manager::DEFAULT_SIZE;
00509 if (this->resize (new_size) == -1)
00510 return -1;
00511 }
00512
00513 ACE_Process_Descriptor &proc_desc =
00514 this->process_table_[this->current_count_];
00515
00516 proc_desc.process_ = proc;
00517 proc_desc.exit_notify_ = event_handler;
00518
00519 #if defined (ACE_WIN32)
00520
00521
00522
00523
00524 ACE_Reactor * const r = this->reactor ();
00525 if (r != 0)
00526 r->register_handler (this, proc->gethandle ());
00527 #endif
00528
00529 ++this->current_count_;
00530 return 0;
00531 }
00532
00533
00534
00535
00536 int
00537 ACE_Process_Manager::insert_proc (ACE_Process *proc,
00538 ACE_Event_Handler *event_handler)
00539 {
00540 ACE_TRACE ("ACE_Process_Manager::insert_proc");
00541
00542
00543
00544 if (this->find_proc (proc->getpid ()) != -1)
00545 return -1;
00546
00547 return this->append_proc (proc, event_handler);
00548 }
00549
00550
00551
00552 int
00553 ACE_Process_Manager::remove (pid_t pid)
00554 {
00555 ACE_TRACE ("ACE_Process_Manager::remove");
00556
00557 ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->lock_, -1));
00558
00559 ssize_t const i = this->find_proc (pid);
00560
00561 if (i != -1)
00562 return this->remove_proc (i);
00563
00564
00565 return -1;
00566 }
00567
00568
00569
00570 int
00571 ACE_Process_Manager::remove_proc (size_t i)
00572 {
00573 ACE_TRACE ("ACE_Process_Manager::remove_proc");
00574
00575
00576
00577
00578 if (this->process_table_[i].exit_notify_ != 0)
00579 {
00580 this->process_table_[i].exit_notify_->handle_close
00581 (this->process_table_[i].process_->gethandle(),
00582 0);
00583 this->process_table_[i].exit_notify_ = 0;
00584 }
00585
00586 #if defined (ACE_WIN32)
00587 ACE_Reactor * const r = this->reactor ();
00588 if (r != 0)
00589 r->remove_handler (this->process_table_[i].process_->gethandle (),
00590 ACE_Event_Handler::DONT_CALL);
00591 #endif
00592
00593 this->process_table_[i].process_->unmanage ();
00594
00595 this->process_table_[i].process_ = 0;
00596
00597 this->current_count_--;
00598
00599 if (this->current_count_ > 0)
00600
00601
00602 this->process_table_[i] =
00603 this->process_table_[this->current_count_];
00604
00605 return 0;
00606 }
00607
00608 int
00609 ACE_Process_Manager::terminate (pid_t pid)
00610 {
00611 ACE_TRACE ("ACE_Process_Manager::terminate");
00612
00613 ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->lock_, -1));
00614
00615
00616
00617 ssize_t const i = this->find_proc (pid);
00618
00619 if (i == -1)
00620
00621 return -1;
00622
00623 int const result = ACE::terminate_process (pid);
00624
00625 if (result != -1)
00626 {
00627
00628 ACE_Errno_Guard error (errno);
00629 this->remove_proc (i);
00630 return 0;
00631 }
00632
00633 return -1;
00634 }
00635
00636 int
00637 ACE_Process_Manager::terminate (pid_t pid,
00638 int sig)
00639 {
00640 ACE_TRACE ("ACE_Process_Manager::terminate");
00641
00642 ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->lock_, -1));
00643
00644
00645
00646 ssize_t const i = this->find_proc (pid);
00647
00648 if (i == -1)
00649
00650 return -1;
00651
00652 return ACE_OS::kill (pid, sig);
00653 }
00654
00655
00656 int
00657 ACE_Process_Manager::set_scheduler (const ACE_Sched_Params & params,
00658 pid_t pid)
00659 {
00660 ACE_TRACE ("ACE_Process_Manager::set_scheduler");
00661
00662 ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex,
00663 ace_mon, this->lock_, -1));
00664
00665
00666
00667 ssize_t const i = this->find_proc (pid);
00668
00669 if (i == -1)
00670
00671 return ACE_INVALID_PID;
00672
00673 return ACE_OS::sched_params (params, pid);
00674 }
00675
00676 int
00677 ACE_Process_Manager::set_scheduler_all (const ACE_Sched_Params & params)
00678 {
00679 ACE_TRACE ("ACE_Process_Manager::set_scheduler_all");
00680
00681 ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex,
00682 ace_mon, this->lock_, -1));
00683
00684 for (size_t i = 0; i < this->current_count_; ++i)
00685 {
00686 pid_t const pid = this->process_table_[i].process_->getpid ();
00687 if (ACE_OS::sched_params (params, pid) != 0)
00688 return -1;
00689 }
00690 return 0;
00691
00692 }
00693
00694
00695
00696
00697
00698 ssize_t
00699 ACE_Process_Manager::find_proc (pid_t pid)
00700 {
00701 ACE_TRACE ("ACE_Process_Manager::find_proc");
00702
00703 for (size_t i = 0; i < this->current_count_; ++i)
00704 if (pid == this->process_table_[i].process_->getpid ())
00705 return i;
00706
00707 return -1;
00708 }
00709
00710 #if defined (ACE_WIN32)
00711
00712
00713
00714 ssize_t
00715 ACE_Process_Manager::find_proc (ACE_HANDLE h)
00716 {
00717 ACE_TRACE ("ACE_Process_Manager::find_proc");
00718
00719 for (size_t i = 0; i < this->current_count_; ++i)
00720 if (h == this->process_table_[i].process_->gethandle ())
00721 return i;
00722
00723 return -1;
00724 }
00725 #endif
00726
00727
00728
00729
00730 int
00731 ACE_Process_Manager::wait (const ACE_Time_Value &timeout)
00732 {
00733 ACE_TRACE ("ACE_Process_Manager::wait");
00734
00735 ACE_Time_Value until = timeout;
00736 ACE_Time_Value remaining = timeout;
00737
00738 if (until < ACE_Time_Value::max_time)
00739 until += ACE_OS::gettimeofday ();
00740
00741 while (this->current_count_ > 0)
00742 {
00743 pid_t const pid = this->wait (0, remaining);
00744
00745 if (pid == ACE_INVALID_PID)
00746 return -1;
00747 else if (pid == 0)
00748 break;
00749
00750 remaining = until < ACE_Time_Value::max_time
00751 ? until - ACE_OS::gettimeofday ()
00752 : ACE_Time_Value::max_time;
00753
00754 if (remaining <= ACE_Time_Value::zero)
00755 break;
00756
00757
00758 }
00759 return static_cast<int> (this->current_count_);
00760 }
00761
00762
00763
00764
00765
00766
00767
00768
00769 pid_t
00770 ACE_Process_Manager::wait (pid_t pid,
00771 ACE_exitcode *status)
00772 {
00773 ACE_TRACE ("ACE_Process_Manager::wait");
00774
00775 return this->wait (pid,
00776 ACE_Time_Value::max_time,
00777 status);
00778 }
00779
00780
00781
00782
00783
00784 pid_t
00785 ACE_Process_Manager::wait (pid_t pid,
00786 const ACE_Time_Value &timeout,
00787 ACE_exitcode *status)
00788 {
00789 ACE_TRACE ("ACE_Process_Manager::wait");
00790
00791 ACE_exitcode local_stat = 0;
00792 if (status == 0)
00793 status = &local_stat;
00794
00795 *status = 0;
00796
00797 ssize_t idx = -1;
00798 ACE_Process *proc = 0;
00799
00800 ACE_MT (ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, this->lock_, -1));
00801
00802 if (pid != 0)
00803 {
00804 idx = this->find_proc (pid);
00805 if (idx == -1)
00806 return ACE_INVALID_PID;
00807 else
00808 proc = process_table_[idx].process_;
00809 }
00810
00811 if (proc != 0)
00812 pid = proc->wait (timeout, status);
00813 else
00814 {
00815
00816 #if defined (ACE_WIN32)
00817 HANDLE *handles = 0;
00818
00819 ACE_NEW_RETURN (handles,
00820 HANDLE[this->current_count_],
00821 ACE_INVALID_PID);
00822
00823 for (size_t i = 0;
00824 i < this->current_count_;
00825 ++i)
00826 handles[i] =
00827 process_table_[i].process_->gethandle ();
00828
00829 DWORD handle_count = static_cast<DWORD> (this->current_count_);
00830 DWORD result = ::WaitForMultipleObjects (handle_count,
00831 handles,
00832 FALSE,
00833 timeout == ACE_Time_Value::max_time
00834 ? INFINITE
00835 : timeout.msec ());
00836 if (result == WAIT_FAILED)
00837 pid = ACE_INVALID_PID;
00838 else if (result == WAIT_TIMEOUT)
00839 pid = 0;
00840 else
00841 {
00842
00843
00844
00845
00846 # if defined (ghs) || defined (__MINGW32__) || (defined (_MSC_VER) && _MSC_VER >= 1300)
00847 ACE_ASSERT (result < WAIT_OBJECT_0 + this->current_count_);
00848 # else
00849 ACE_ASSERT (result >= WAIT_OBJECT_0
00850 && result < WAIT_OBJECT_0 + this->current_count_);
00851 # endif
00852
00853 idx = this->find_proc (handles[result - WAIT_OBJECT_0]);
00854
00855 if (idx != -1)
00856 {
00857 pid = process_table_[idx].process_->getpid ();
00858 result = ::GetExitCodeProcess (handles[result - WAIT_OBJECT_0],
00859 status);
00860 if (result == 0)
00861 {
00862
00863 this->remove_proc (idx);
00864 pid = ACE_INVALID_PID;
00865 }
00866 }
00867 else
00868 {
00869
00870
00871 delete [] handles;
00872 ACE_ERROR_RETURN ((LM_ERROR,
00873 ACE_LIB_TEXT ("Process removed")
00874 ACE_LIB_TEXT (" -- somebody's ignoring the lock!\n")),
00875 -1);
00876 }
00877 }
00878
00879 delete [] handles;
00880 #else
00881 if (timeout == ACE_Time_Value::max_time)
00882 {
00883 pid = ACE_OS::waitpid (-1, status, 0);
00884 }
00885 else if (timeout == ACE_Time_Value::zero)
00886 {
00887 pid = ACE_OS::waitpid (-1, status, WNOHANG);
00888 }
00889 else
00890 {
00891 # if defined (ACE_LACKS_UNIX_SIGNALS)
00892 pid = 0;
00893 ACE_Time_Value sleeptm (1);
00894 if (sleeptm > timeout)
00895 sleeptm = timeout;
00896 ACE_Time_Value tmo (timeout);
00897 for (ACE_Countdown_Time time_left (&tmo); tmo > ACE_Time_Value::zero ; time_left.update ())
00898 {
00899 pid = ACE_OS::waitpid (-1, status, WNOHANG);
00900 if (pid > 0 || pid == ACE_INVALID_PID)
00901 break;
00902
00903
00904
00905 ACE_OS::sleep (sleeptm);
00906 }
00907 # else
00908
00909
00910
00911
00912
00913 ACE_Sig_Action old_action;
00914 if (this->reactor () == 0)
00915 {
00916 ACE_Sig_Action do_sigchld ((ACE_SignalHandler)sigchld_nop);
00917 do_sigchld.register_action (SIGCHLD, &old_action);
00918 }
00919
00920 ACE_Time_Value tmo (timeout);
00921 for (ACE_Countdown_Time time_left (&tmo); ; time_left.update ())
00922 {
00923 pid = ACE_OS::waitpid (-1, status, WNOHANG);
00924 # if defined (ACE_VXWORKS) && (ACE_VXWORKS >= 0x600)
00925 if (pid > 0 || (pid == ACE_INVALID_PID && errno != EINTR))
00926 # else
00927 if (pid > 0 || pid == ACE_INVALID_PID)
00928 # endif
00929 break;
00930
00931
00932
00933
00934
00935
00936 if (-1 == ACE_OS::sleep (tmo) && errno == EINTR)
00937 continue;
00938
00939 pid = 0;
00940 break;
00941 }
00942
00943
00944 if (this->reactor () == 0)
00945 {
00946 old_action.register_action (SIGCHLD);
00947 }
00948 # endif
00949 }
00950 #endif
00951 }
00952
00953 if (pid != ACE_INVALID_PID && pid != 0)
00954 {
00955 if (proc == 0)
00956 {
00957 idx = this->find_proc (pid);
00958 if (idx == -1)
00959 {
00960
00961 ACE_DEBUG ((LM_DEBUG,
00962 ACE_LIB_TEXT ("(%P|%t) oops, reaped unmanaged %d\n"),
00963 pid));
00964 return pid;
00965 }
00966 else
00967 proc = process_table_[idx].process_;
00968 }
00969 else
00970 ACE_ASSERT (pid == proc->getpid ());
00971
00972 this->notify_proc_handler (idx,
00973 *status);
00974 this->remove (pid);
00975 }
00976
00977 return pid;
00978 }
00979
00980
00981
00982 int
00983 ACE_Process_Manager::reap (pid_t pid,
00984 ACE_exitcode *stat_loc,
00985 int options)
00986 {
00987 ACE_TRACE ("ACE_Process_Manager::reap");
00988
00989 return this->wait (pid,
00990 (ACE_BIT_ENABLED (options, WNOHANG)
00991 ? ACE_Time_Value::zero
00992 : ACE_Time_Value::max_time),
00993 stat_loc);
00994 }
00995
00996
00997
00998
00999
01000 int
01001 ACE_Process_Manager::notify_proc_handler (size_t i,
01002 ACE_exitcode exit_code)
01003 {
01004 if (i < this->current_count_)
01005 {
01006 ACE_Process_Descriptor &proc_desc =
01007 this->process_table_[i];
01008
01009 proc_desc.process_->exit_code (exit_code);
01010
01011 if (proc_desc.exit_notify_ != 0)
01012 proc_desc.exit_notify_->handle_exit (proc_desc.process_);
01013 else if (this->default_exit_handler_ != 0
01014 && this->default_exit_handler_->handle_exit (proc_desc.process_) < 0)
01015 {
01016 this->default_exit_handler_->handle_close
01017 (ACE_INVALID_HANDLE,
01018 0);
01019 this->default_exit_handler_ = 0;
01020 }
01021 return 1;
01022 }
01023 else
01024 {
01025 ACE_DEBUG ((LM_DEBUG,
01026 ACE_LIB_TEXT ("(%P:%t|%T) ACE_Process_Manager::notify_proc_handler:")
01027 ACE_LIB_TEXT (" unknown/unmanaged process reaped\n")));
01028 return 0;
01029 }
01030 }
01031
01032 ACE_END_VERSIONED_NAMESPACE_DECL