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