Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'winsup/cygwin/sigproc.cc')
-rw-r--r--winsup/cygwin/sigproc.cc217
1 files changed, 91 insertions, 126 deletions
diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc
index 7b55487bb..091065241 100644
--- a/winsup/cygwin/sigproc.cc
+++ b/winsup/cygwin/sigproc.cc
@@ -1,6 +1,6 @@
/* sigproc.cc: inter/intra signal and sub process handler
- Copyright 1997, 1998, 1999, 2000, 2001 Red Hat, Inc.
+ Copyright 1997, 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
Written by Christopher Faylor <cgf@cygnus.com>
@@ -17,6 +17,7 @@ details. */
#include <errno.h>
#include <stdlib.h>
#include <sys/cygwin.h>
+#include <assert.h>
#include "cygerrno.h"
#include "sync.h"
#include "sigproc.h"
@@ -26,11 +27,11 @@ details. */
#include "path.h"
#include "dtable.h"
#include "cygheap.h"
-#include "child_info.h"
+#include "child_info_magic.h"
#define NEED_VFORK
#include "perthread.h"
-#include <assert.h>
#include "shared_info.h"
+#include "cygthread.h"
/*
* Convenience defines
@@ -79,34 +80,38 @@ HANDLE NO_COPY signal_arrived; // Event signaled when a signal has
Static DWORD proc_loop_wait = 1000; // Wait for subprocesses to exit
Static DWORD sig_loop_wait = INFINITE; // Wait for signals to arrive
-Static HANDLE sigcatch_nonmain = NULL; // The semaphore signaled when
+Static HANDLE sigcatch_nonmain; // The semaphore signaled when
// signals are available for
// processing from non-main thread
-Static HANDLE sigcatch_main = NULL; // Signalled when main thread sends a
+Static HANDLE sigcatch_main; // Signalled when main thread sends a
// signal
-Static HANDLE sigcatch_nosync = NULL; // Signal wait_sig to scan sigtodo
+Static HANDLE sigcatch_nosync; // Signal wait_sig to scan sigtodo
// but not to bother with any
// synchronization
-Static HANDLE sigcomplete_main = NULL; // Event signaled when a signal has
+Static HANDLE sigcomplete_main; // Event signaled when a signal has
// finished processing for the main
// thread
-Static HANDLE sigcomplete_nonmain = NULL;// Semaphore raised for non-main
+Static HANDLE sigcomplete_nonmain; // Semaphore raised for non-main
// threads when a signal has finished
// processing
-Static HANDLE hwait_sig = NULL; // Handle of wait_sig thread
-Static HANDLE hwait_subproc = NULL; // Handle of sig_subproc thread
+HANDLE NO_COPY sigCONT; // Used to "STOP" a process
+Static cygthread *hwait_sig; // Handle of wait_sig thread
+Static cygthread *hwait_subproc; // Handle of sig_subproc thread
-Static HANDLE wait_sig_inited = NULL; // Control synchronization of
+Static HANDLE wait_sig_inited; // Control synchronization of
// message queue startup
/* Used by WaitForMultipleObjects. These are handles to child processes.
*/
-Static HANDLE events[PSIZE + 1] = {0}; // All my children's handles++
+Static HANDLE events[PSIZE + 1]; // All my children's handles++
#define hchildren (events + 1) // Where the children handles begin
-Static pinfo pchildren[PSIZE]; // All my children info
-Static int nchildren = 0; // Number of active children
-Static pinfo zombies[NZOMBIES]; // All my deceased children info
-Static int nzombies = 0; // Number of deceased children
+Static char cpchildren[PSIZE * sizeof (pinfo)]; // All my children info
+Static int nchildren; // Number of active children
+Static char czombies[(NZOMBIES + 1) * sizeof (pinfo)]; // All my deceased children info
+Static int nzombies; // Number of deceased children
+
+#define pchildren ((pinfo *) cpchildren)
+#define zombies ((pinfo *) czombies)
Static waitq waitq_head = {0, 0, 0, 0, 0, 0, 0};// Start of queue for wait'ing threads
Static waitq waitq_main; // Storage for main thread
@@ -164,19 +169,36 @@ out:
return res;
}
-__inline static void
-wait_for_me ()
+void __stdcall
+wait_for_sigthread ()
{
- /* See if this is the first signal call after initialization.
- * If so, wait for notification that all initialization has completed.
- * Then set the handle to NULL to avoid checking this again.
- */
- if (wait_sig_inited)
+ assert (wait_sig_inited);
+ (void) WaitForSingleObject (wait_sig_inited, INFINITE);
+ (void) ForceCloseHandle (wait_sig_inited);
+ wait_sig_inited = NULL;
+}
+
+/* Get the sync_proc_subproc muto to control access to
+ * children, zombie arrays.
+ * Attempt to handle case where process is exiting as we try to grab
+ * the mutex.
+ */
+static BOOL
+get_proc_lock (DWORD what, DWORD val)
+{
+ Static int lastwhat = -1;
+ if (!sync_proc_subproc)
+ return FALSE;
+ if (sync_proc_subproc->acquire (WPSP))
{
- (void) WaitForSingleObject (wait_sig_inited, INFINITE);
- (void) ForceCloseHandle (wait_sig_inited);
- wait_sig_inited = NULL;
+ lastwhat = what;
+ return TRUE;
}
+ if (!sync_proc_subproc)
+ return FALSE;
+ system_printf ("Couldn't aquire sync_proc_subproc for(%d,%d), %E, last %d",
+ what, val, lastwhat);
+ return TRUE;
}
static BOOL __stdcall
@@ -184,7 +206,7 @@ proc_can_be_signalled (_pinfo *p)
{
if (p == myself_nowait || p == myself_nowait_nonmain || p == myself)
{
- wait_for_me ();
+ assert (!wait_sig_inited);
return 1;
}
@@ -205,7 +227,7 @@ pid_exists (pid_t pid)
BOOL __stdcall
proc_exists (_pinfo *p)
{
- return p && !(p->process_state & (PID_INITIALIZING | PID_EXITED));
+ return p && !(p->process_state & PID_EXITED);
}
/* Return 1 if this is one of our children, zero otherwise.
@@ -292,12 +314,14 @@ proc_subproc (DWORD what, DWORD val)
if (hchildren[val] != pchildren[val]->hProcess)
{
sigproc_printf ("pid %d[%d], reparented old hProcess %p, new %p",
- pchildren[val]->pid, val, hchildren[val], pchildren[val]->hProcess);
- ForceCloseHandle1 (hchildren[val], childhProc);
+ pchildren[val]->pid, val, hchildren[val], pchildren[val]->hProcess);
+ HANDLE h = hchildren[val];
hchildren[val] = pchildren[val]->hProcess; /* Filled out by child */
+ sync_proc_subproc->release (); // Release the lock ASAP
+ ForceCloseHandle1 (h, childhProc);
ProtectHandle1 (pchildren[val]->hProcess, childhProc);
rc = 0;
- break; // This was an exec()
+ goto out; // This was an exec()
}
sigproc_printf ("pid %d[%d] terminated, handle %p, nchildren %d, nzombies %d",
@@ -432,22 +456,12 @@ proc_terminate (void)
/* Signal processing is assumed to be blocked in this routine. */
if (hwait_subproc)
{
- int rc;
proc_loop_wait = 0; // Tell wait_subproc thread to exit
wake_wait_subproc (); // Wake wait_subproc loop
-
- /* Wait for wait_subproc thread to exit (but not *too* long) */
- if ((rc = WaitForSingleObject (hwait_subproc, WWSP)) != WAIT_OBJECT_0)
- if (rc == WAIT_TIMEOUT)
- system_printf ("WFSO(hwait_subproc) timed out");
- else
- system_printf ("WFSO(hwait_subproc), rc %d, %E", rc);
-
- HANDLE h = hwait_subproc;
+ hwait_subproc->detach ();
hwait_subproc = NULL;
- ForceCloseHandle1 (h, hwait_subproc);
- sync_proc_subproc->acquire(WPSP);
+ sync_proc_subproc->acquire (WPSP);
(void) proc_subproc (PROC_CLEARWAIT, 1);
/* Clean out zombie processes from the pid list. */
@@ -460,7 +474,7 @@ proc_terminate (void)
ForceCloseHandle1 (zombies[i]->pid_handle, pid_handle);
}
zombies[i]->process_state = PID_EXITED; /* CGF FIXME - still needed? */
- zombies[i].release(); // FIXME: this breaks older gccs for some reason
+ zombies[i].release (); // FIXME: this breaks older gccs for some reason
}
/* Disassociate my subprocesses */
@@ -517,7 +531,7 @@ sig_dispatch_pending (int justwake)
#endif
else
{
- wait_for_me ();
+ assert (!wait_sig_inited);
if (!justwake)
(void) sig_send (myself, __SIGFLUSH);
else if (ReleaseSemaphore (sigcatch_nosync, 1, NULL))
@@ -550,21 +564,15 @@ sigproc_init ()
/* local event signaled when main thread has been dispatched
to a signal handler function. */
- signal_arrived = CreateEvent(&sec_none_nih, TRUE, FALSE, NULL);
+ signal_arrived = CreateEvent (&sec_none_nih, TRUE, FALSE, NULL);
ProtectHandle (signal_arrived);
- if (!(hwait_sig = makethread (wait_sig, NULL, 0, "sig")))
- {
- system_printf ("cannot create wait_sig thread, %E");
- api_fatal ("terminating");
- }
-
- ProtectHandle (hwait_sig);
+ hwait_sig = new cygthread (wait_sig, cygself, "sig");
/* sync_proc_subproc is used by proc_subproc. It serialises
* access to the children and zombie arrays.
*/
- sync_proc_subproc = new_muto (FALSE, "sync_proc_subproc");
+ new_muto (sync_proc_subproc);
/* Initialize waitq structure for main thread. A waitq structure is
* allocated for each thread that executes a wait to allow multiple threads
@@ -588,7 +596,6 @@ sigproc_init ()
void __stdcall
sigproc_terminate (void)
{
- HANDLE h = hwait_sig;
hwait_sig = NULL;
if (GetCurrentThreadId () == sigtid)
@@ -610,29 +617,6 @@ sigproc_terminate (void)
sigproc_printf ("entering");
sig_loop_wait = 0; // Tell wait_sig to exit when it is
// finished with anything it is doing
- // sig_dispatch_pending (TRUE); // wake up and die
- /* In case of a sigsuspend */
- SetEvent (signal_arrived);
-
- /* If !hwait_sig, then the process probably hasn't even finished
- * its initialization phase.
- */
- if (0 && hwait_sig)
- {
- if (GetCurrentThreadId () != sigtid)
- WaitForSingleObject (h, 10000);
- ForceCloseHandle1 (h, hwait_sig);
-
-
- if (GetCurrentThreadId () != sigtid)
- {
- ForceCloseHandle (sigcomplete_main);
- ForceCloseHandle (sigcomplete_nonmain);
- ForceCloseHandle (sigcatch_main);
- ForceCloseHandle (sigcatch_nonmain);
- ForceCloseHandle (sigcatch_nosync);
- }
- }
sigproc_printf ("done");
}
@@ -669,7 +653,7 @@ sig_send (_pinfo *p, int sig, DWORD ebp, bool exception)
{
if (no_signals_available ())
goto out; // Either exiting or not yet initializing
- wait_for_me ();
+ assert (!wait_sig_inited);
wait_for_completion = p != myself_nowait;
p = myself;
}
@@ -820,11 +804,9 @@ subproc_init (void)
* the hchildren array.
*/
events[0] = CreateEvent (&sec_none_nih, FALSE, FALSE, NULL);
- if (!(hwait_subproc = makethread (wait_subproc, NULL, 0, "proc")))
- system_printf ("cannot create wait_subproc thread, %E");
+ hwait_subproc = new cygthread (wait_subproc, NULL, "proc");
ProtectHandle (events[0]);
- ProtectHandle (hwait_subproc);
- sigproc_printf ("started wait_subproc thread %p", hwait_subproc);
+ sigproc_printf ("started wait_subproc thread %p", (HANDLE) *hwait_subproc);
}
/* Initialize some of the memory block passed to child processes
@@ -834,11 +816,15 @@ void __stdcall
init_child_info (DWORD chtype, child_info *ch, pid_t pid, HANDLE subproc_ready)
{
memset (ch, 0, sizeof *ch);
- ch->cb = sizeof *ch;
+ ch->cb = chtype == PROC_FORK ? sizeof (child_info_fork) : sizeof (child_info);
+ ch->intro = PROC_MAGIC_GENERIC;
+ ch->magic = CHILD_INFO_MAGIC;
ch->type = chtype;
ch->cygpid = pid;
ch->subproc_ready = subproc_ready;
ch->pppid_handle = myself->ppid_handle;
+ ch->fhandler_union_cb = sizeof (fhandler_union);
+ ch->mount_h = cygwin_mount_h;
}
/* Check the state of all of our children to see if any are stopped or
@@ -899,7 +885,8 @@ getsem (_pinfo *p, const char *str, int init, int max)
set_errno (ESRCH);
return NULL;
}
- int wait = 10000;
+ int wait = 1000;
+ /* Wait for new process to generate its semaphores. */
sigproc_printf ("pid %d, ppid %d, wait %d, initializing %x", p->pid, p->ppid, wait,
ISSTATE (p, PID_INITIALIZING));
for (int i = 0; ISSTATE (p, PID_INITIALIZING) && i < wait; i++)
@@ -912,56 +899,33 @@ getsem (_pinfo *p, const char *str, int init, int max)
char sa_buf[1024];
DWORD winpid = GetCurrentProcessId ();
- h = CreateSemaphore (allow_ntsec ? sec_user_nih (sa_buf) : &sec_none_nih,
- init, max, str = shared_name (str, winpid));
+ h = CreateSemaphore (sec_user_nih (sa_buf), init, max,
+ str = shared_name (str, winpid));
p = myself;
+ if (!h)
+ {
+ system_printf ("can't create semaphore %s, %E", str);
+ __seterrno ();
+ }
}
else
{
h = OpenSemaphore (SEMAPHORE_ALL_ACCESS, FALSE,
- str = shared_name (str, p->dwProcessId));
+ shared_name (str, p->dwProcessId));
- if (h == NULL)
+ if (!h)
{
if (GetLastError () == ERROR_FILE_NOT_FOUND && !proc_exists (p))
- set_errno (ESRCH);
+ set_errno (ESRCH); /* No such process */
else
- set_errno (EPERM);
- return NULL;
+ set_errno (EPERM); /* Couldn't access the semaphore --
+ different cygwin DLL maybe? */
}
}
- if (!h)
- {
- system_printf ("can't %s %s, %E", p ? "open" : "create", str);
- set_errno (ESRCH);
- }
return h;
}
-/* Get the sync_proc_subproc muto to control access to
- * children, zombie arrays.
- * Attempt to handle case where process is exiting as we try to grab
- * the mutex.
- */
-static BOOL
-get_proc_lock (DWORD what, DWORD val)
-{
- Static int lastwhat = -1;
- if (!sync_proc_subproc)
- return FALSE;
- if (sync_proc_subproc->acquire (WPSP))
- {
- lastwhat = what;
- return TRUE;
- }
- if (!sync_proc_subproc)
- return FALSE;
- system_printf ("Couldn't aquire sync_proc_subproc for(%d,%d), %E, last %d",
- what, val, lastwhat);
- return TRUE;
-}
-
/* Remove a zombie from zombies by swapping it with the last child in the list.
*/
static void __stdcall
@@ -1063,10 +1027,10 @@ stopped_or_terminated (waitq *parent_w, _pinfo *child)
* has been handled, as per POSIX.
*/
static DWORD WINAPI
-wait_sig (VOID *)
+wait_sig (VOID *self)
{
/* Initialization */
- (void) SetThreadPriority (hwait_sig, WAIT_SIG_PRIORITY);
+ (void) SetThreadPriority (*((cygthread *) self), WAIT_SIG_PRIORITY);
/* sigcatch_nosync - semaphore incremented by sig_dispatch_pending and
* by foreign processes to force an examination of
@@ -1085,6 +1049,7 @@ wait_sig (VOID *)
sigcomplete_nonmain = CreateSemaphore (&sec_none_nih, 0, MAXLONG, NULL);
sigcomplete_main = CreateEvent (&sec_none_nih, FALSE, FALSE, NULL);
sigproc_printf ("sigcatch_nonmain %p, sigcatch_main %p", sigcatch_nonmain, sigcatch_main);
+ sigCONT = CreateEvent (&sec_none_nih, FALSE, FALSE, NULL);
/* Setting dwProcessId flags that this process is now capable of receiving
* signals. Prior to this, dwProcessId was set to the windows pid of
@@ -1110,7 +1075,7 @@ wait_sig (VOID *)
debug_printf ("subproc_ready %p", child_proc_info->subproc_ready);
if (!SetEvent (child_proc_info->subproc_ready))
system_printf ("SetEvent (subproc_ready) failed, %E");
- ForceCloseHandle (child_proc_info->subproc_ready);
+ ForceCloseHandle1 (child_proc_info->subproc_ready, subproc_ready);
/* Initialize an "indirect" pid block so that if someone looks up this
process via its Windows PID it will be redirected to the appropriate
Cygwin PID shared memory block. */
@@ -1178,15 +1143,15 @@ wait_sig (VOID *)
/* just forcing the loop */
break;
- /* Internal signal to force a flush of strace data to disk. */
+ /* Internal signal to turn on stracing. */
case __SIGSTRACE:
- // proc_strace (); // Dump cached strace.prntf stuff.
+ strace.hello ();
break;
/* A normal UNIX signal */
default:
sigproc_printf ("Got signal %d", sig);
- int wasdispatched = sig_handle (sig);
+ int wasdispatched = sig_handle (sig, rc != 2);
if (sig == SIGCHLD && wasdispatched)
dispatched_sigchld = 1;
/* Need to decrement again to offset increment below since