summaryrefslogtreecommitdiff
path: root/ace/Process_Manager.cpp
diff options
context:
space:
mode:
authorSteve Huston <shuston@riverace.com>2002-01-26 01:00:51 +0000
committerSteve Huston <shuston@riverace.com>2002-01-26 01:00:51 +0000
commitd27e74f0d0a6343cb29f0ff9eaadfef954cc973b (patch)
treebe4b817ba6738e3d4cffd8bd0b6d5d63593ab2c5 /ace/Process_Manager.cpp
parentb6af49610848d861b95cc9180b1e37b4f927ac7c (diff)
downloadATCD-d27e74f0d0a6343cb29f0ff9eaadfef954cc973b.tar.gz
ChangeLogTag:Fri Jan 25 19:58:41 2002 Steve Huston <shuston@riverace.com>
Diffstat (limited to 'ace/Process_Manager.cpp')
-rw-r--r--ace/Process_Manager.cpp93
1 files changed, 55 insertions, 38 deletions
diff --git a/ace/Process_Manager.cpp b/ace/Process_Manager.cpp
index 46d5eb58c6d..b0df10a8a62 100644
--- a/ace/Process_Manager.cpp
+++ b/ace/Process_Manager.cpp
@@ -193,28 +193,13 @@ ACE_Process_Manager::open (size_t size,
{
ACE_TRACE ("ACE_Process_Manager::open");
-#if !defined (ACE_LACKS_SETPGID)
- // Set up a process group so that the thread that opened this
- // Manager will be able to put children into its own group and wait
- // for them.
- if (ACE_OS::setpgid (0, 0) == -1)
- ACE_ERROR ((LM_WARNING,
- ACE_LIB_TEXT ("%p.\n"),
- ACE_LIB_TEXT ("ACE_Process_Manager::open: can't create a ")
- ACE_LIB_TEXT ("process group; some wait functions may fail")));
-#endif /* ACE_LACKS_SETPGID */
-
if (r)
{
- ACE_Event_Handler::reactor (r);
+ this->reactor (r);
#if !defined (ACE_WIN32) && !defined (ACE_PSOS)
// Register signal handler object.
- if (reactor ()->register_handler
- (SIGCHLD, this) == -1)
- ACE_ERROR ((LM_ERROR,
- "%p\n%a",
- "register_handler",
- 1));
+ if (r->register_handler (SIGCHLD, this) == -1)
+ return -1;
#endif // !defined(ACE_WIN32) && !defined (ACE_PSOS)
}
@@ -379,9 +364,7 @@ ACE_Process_Manager::register_handler (ACE_Event_Handler *eh,
if (pid == ACE_INVALID_PID)
{
if (this->default_exit_handler_ != 0)
- this->default_exit_handler_->handle_close
- (ACE_INVALID_HANDLE,
- 0);
+ this->default_exit_handler_->handle_close (ACE_INVALID_HANDLE, 0);
this->default_exit_handler_ = eh;
return 0;
}
@@ -389,15 +372,13 @@ ACE_Process_Manager::register_handler (ACE_Event_Handler *eh,
ssize_t i = this->find_proc (pid);
if (i == -1)
- // set "process not found" error
+ errno = ECHILD;
return -1;
ACE_Process_Descriptor &proc_desc = this->process_table_[i];
if (proc_desc.exit_notify_ != 0)
- proc_desc.exit_notify_->handle_close
- (ACE_INVALID_HANDLE,
- 0);
+ proc_desc.exit_notify_->handle_close (ACE_INVALID_HANDLE, 0);
proc_desc.exit_notify_ = eh;
return 0;
}
@@ -423,9 +404,6 @@ ACE_Process_Manager::spawn (ACE_Process *process,
{
ACE_TRACE ("ACE_Process_Manager::spawn");
- if (options.getgroup () == ACE_INVALID_PID)
- options.setgroup (ACE_OS::getpid ());
-
pid_t pid = process->spawn (options);
// Only include the pid in the parent's table.
@@ -834,15 +812,52 @@ ACE_Process_Manager::wait (pid_t pid,
pid = ACE_OS::waitpid (-(ACE_OS::getpid()),
status,
WNOHANG);
- if (pid != 0)
- // "no such children" error, or got one!
- break;
-
- ACE_Sig_Set alarm_or_child;
-
- alarm_or_child.sig_add (SIGALRM);
- alarm_or_child.sig_add (SIGCHLD);
-
+ if (pid > 0)
+ break; // Got one - all done
+ if (pid == -1)
+ {
+ if (errno == EINTR)
+ continue; // Try again
+ break; // Real error - give up
+ }
+ // pid 0, nothing is ready yet, so wait.
+
+ ACE_Sig_Set wait_for_sigs;
+
+ wait_for_sigs.sig_add (SIGCHLD);
+
+# if defined (ACE_HAS_SIGTIMEDWAIT)
+ // Block SIGCHLD then wait for it.
+ sigset_t orig_set;
+# if defined (ACE_HAS_THREADS)
+ ACE_OS::thr_sigsetmask (SIG_BLOCK, wait_for_sigs, &orig_set);
+# else
+ ACE_OS::sigprocmask (SIG_BLOCK, wait_for_sigs, &orig_set);
+# endif
+ int status = ACE_OS::sigtimedwait (wait_for_sigs,
+ 0,
+ &timeout);
+ {
+ ACE_Errno_Guard guard (errno);
+# if defined (ACE_HAS_THREADS)
+ ACE_OS::thr_sigsetmask (SIG_BLOCK, wait_for_sigs, &orig_set);
+# else
+ ACE_OS::sigprocmask (SIG_SETMASK, &orig_set, 0);
+# endif
+ }
+ if (-1 != status || errno == EINTR)
+ continue; // SIGCHLD ready; go waitpid again
+ // Here if there was a timeout or error. If timeout,
+ // it's not an error for our caller, just return 0.
+ pid = (errno == EAGAIN ? 0 : ACE_INVALID_PID);
+ break;
+# else
+ // Without sigtimedwait support, this can get hairy... we
+ // set an alarm to fire at the caller-specified future time.
+ // Then we wait for either SIGCHLD or SIGALRM. The problem with
+ // this is that once ualarm is enabled, the SIGALRM will fire
+ // whether we're still here waiting or not. On some platforms,
+ // this will cause a core dump on uncaught signal.
ACE_Time_Value time_left = wait_until - ACE_OS::gettimeofday ();
// if ACE_OS::ualarm doesn't have sub-second resolution:
@@ -854,8 +869,10 @@ ACE_Process_Manager::wait (pid_t pid,
break;
}
+ wait_for_sigs.sig_add (SIGALRM);
ACE_OS::ualarm (time_left);
- ACE_OS::sigwait (alarm_or_child);
+ ACE_OS::sigwait (wait_for_sigs);
+# endif /* ACE_HAS_SIGTIMEDWAIT */
}
}
#endif /* !defined (ACE_WIN32) */