* shared_info.h (CURR_MOUNT_MAGIC): Fix.

* sigproc.cc (sigpacket): New structure.
(sig_send): Fill out sigpacket structure to send to signal thread rather than
racily sending separate packets.
(wait_sig): Use sigpacket structure to receive info from signal sender.
This commit is contained in:
Christopher Faylor 2003-09-25 03:06:36 +00:00
parent 64f74184bb
commit 7759daa979
3 changed files with 71 additions and 69 deletions

View File

@ -1,3 +1,12 @@
2003-09-24 Christopher Faylor <cgf@redhat.com>
* shared_info.h (CURR_MOUNT_MAGIC): Fix.
* sigproc.cc (sigpacket): New structure.
(sig_send): Fill out sigpacket structure to send to signal thread
rather than racily sending separate packets.
(wait_sig): Use sigpacket structure to receive info from signal sender.
2003-09-24 Pierre Humblet <pierre.humblet@ieee.org> 2003-09-24 Pierre Humblet <pierre.humblet@ieee.org>
* shared_info.h (class user_info): New. * shared_info.h (class user_info): New.

View File

@ -44,7 +44,7 @@ class mount_item
#define USER_VERSION 1 // increment when mount table changes and #define USER_VERSION 1 // increment when mount table changes and
#define USER_VERSION_MAGIC CYGWIN_VERSION_MAGIC (MOUNT_MAGIC, USER_VERSION) #define USER_VERSION_MAGIC CYGWIN_VERSION_MAGIC (MOUNT_MAGIC, USER_VERSION)
#define CURR_MOUNT_MAGIC 0x4fe431cdU /* FIXME */ #define CURR_MOUNT_MAGIC 0x6dd73a3fU
class reg_key; class reg_key;
struct device; struct device;

View File

@ -72,6 +72,14 @@ public:
friend int __stdcall sig_dispatch_pending (); friend int __stdcall sig_dispatch_pending ();
}; };
struct sigpacket
{
int sig;
pid_t pid;
HANDLE wakeup;
sigset_t *mask;
};
static pending_signals sigqueue; static pending_signals sigqueue;
struct sigaction *global_sigs; struct sigaction *global_sigs;
@ -652,10 +660,10 @@ sig_send (_pinfo *p, int sig, DWORD ebp, bool exception)
int rc = 1; int rc = 1;
DWORD tid = GetCurrentThreadId (); DWORD tid = GetCurrentThreadId ();
BOOL its_me; BOOL its_me;
HANDLE thiscomplete;
HANDLE sendsig; HANDLE sendsig;
bool wait_for_completion; bool wait_for_completion;
sigframe thisframe; sigframe thisframe;
sigpacket pack;
if (p == myself_nowait_nonmain) if (p == myself_nowait_nonmain)
p = (tid == mainthread.id) ? (_pinfo *) myself : myself_nowait; p = (tid == mainthread.id) ? (_pinfo *) myself : myself_nowait;
@ -691,7 +699,7 @@ sig_send (_pinfo *p, int sig, DWORD ebp, bool exception)
{ {
if (tid == mainthread.id) if (tid == mainthread.id)
thisframe.init (mainthread, ebp, exception); thisframe.init (mainthread, ebp, exception);
thiscomplete = sigcomplete_main; pack.wakeup = sigcomplete_main;
} }
} }
else else
@ -708,15 +716,26 @@ sig_send (_pinfo *p, int sig, DWORD ebp, bool exception)
__seterrno (); __seterrno ();
goto out; goto out;
} }
thiscomplete = NULL; pack.wakeup = NULL;
} }
sigset_t pending;
if (!its_me)
pack.mask = NULL;
else if (sig == __SIGPENDING)
pack.mask = &pending;
else if (sig == __SIGFLUSH || sig > 0)
pack.mask = &myself->getsigmask ();
else
pack.mask = NULL;
pack.sig = sig;
pack.pid = myself->pid;
DWORD nb; DWORD nb;
if (!WriteFile (sendsig, &sig, sizeof (sig), &nb, NULL) || nb != sizeof (sig)) if (!WriteFile (sendsig, &pack, sizeof (pack), &nb, NULL) || nb != sizeof (pack))
{ {
/* Couldn't signal the semaphore. This probably means that the /* Couldn't send to the pipe. This probably means that the
* process is exiting. process is exiting. */
*/
if (!its_me) if (!its_me)
{ {
__seterrno (); __seterrno ();
@ -733,48 +752,25 @@ sig_send (_pinfo *p, int sig, DWORD ebp, bool exception)
goto out; goto out;
} }
/* Write completion handle or NULL */
if (!WriteFile (sendsig, &thiscomplete, sizeof (thiscomplete), &nb, NULL)
|| nb != sizeof (thiscomplete))
{
__seterrno ();
goto out;
}
sigset_t pending;
sigset_t *mask;
if (sig == __SIGPENDING)
mask = &pending;
else if (sig == __SIGFLUSH || sig > 0)
mask = &myself->getsigmask ();
else
mask = NULL;
if (mask && !WriteFile (sendsig, &mask, sizeof (mask), &nb, NULL)
|| nb != sizeof (pending))
{
__seterrno ();
goto out;
}
/* No need to wait for signal completion unless this was a signal to /* No need to wait for signal completion unless this was a signal to
* this process. this process.
*
* If it was a signal to this process, wait for a dispatched signal. If it was a signal to this process, wait for a dispatched signal.
* Otherwise just wait for the wait_sig to signal that it has finished Otherwise just wait for the wait_sig to signal that it has finished
* processing the signal. processing the signal. */
*/ if (wait_for_completion)
if (!wait_for_completion) {
sigproc_printf ("Waiting for pack.wakeup %p", pack.wakeup);
rc = WaitForSingleObject (pack.wakeup, WSSC);
}
else
{ {
rc = WAIT_OBJECT_0; rc = WAIT_OBJECT_0;
sigproc_printf ("Not waiting for sigcomplete. its_me %d signal %d", its_me, sig); sigproc_printf ("Not waiting for sigcomplete. its_me %d signal %d", its_me, sig);
if (!its_me) if (!its_me)
ForceCloseHandle (sendsig); ForceCloseHandle (sendsig);
} }
else
{
sigproc_printf ("Waiting for thiscomplete %p", thiscomplete);
rc = WaitForSingleObject (thiscomplete, WSSC);
}
if (rc == WAIT_OBJECT_0) if (rc == WAIT_OBJECT_0)
rc = 0; // Successful exit rc = 0; // Successful exit
@ -1088,32 +1084,29 @@ wait_sig (VOID *self)
for (;;) for (;;)
{ {
int sig;
DWORD nb; DWORD nb;
if (!ReadFile (readsig, &sig, sizeof (sig), &nb, NULL)) sigpacket pack;
if (!ReadFile (readsig, &pack, sizeof (pack), &nb, NULL))
break; break;
HANDLE wakeup; if (nb != sizeof (pack))
if (!ReadFile (readsig, &wakeup, sizeof (wakeup), &nb, NULL)
|| nb != sizeof (wakeup))
{ {
system_printf ("signal notification handle read failure, %E"); system_printf ("short read from signal pipe: %d != %d", nb,
sizeof (pack));
continue; continue;
} }
if (!sig) if (!pack.sig)
continue; /* Just checking to see if we exist */ continue; /* Just checking to see if we exist */
sigset_t *mask; sigset_t dummy_mask;
if ((sig == __SIGFLUSH || sig == __SIGPENDING || sig > 0) if (!pack.mask)
&& (!ReadFile (readsig, &mask, sizeof (mask), &nb, NULL)
|| nb != sizeof (mask)))
{ {
system_printf ("signal mask handle read failure, %E"); dummy_mask = myself->getsigmask ();
continue; pack.mask = &dummy_mask;
} }
switch (sig) switch (pack.sig)
{ {
case __SIGCOMMUNE: case __SIGCOMMUNE:
talktome (); talktome ();
@ -1122,35 +1115,35 @@ wait_sig (VOID *self)
strace.hello (); strace.hello ();
continue; continue;
case __SIGPENDING: case __SIGPENDING:
*mask = 0; *pack.mask = 0;
unsigned bit; unsigned bit;
sigqueue.reset (); sigqueue.reset ();
while ((sig = sigqueue.next ())) while ((pack.sig = sigqueue.next ()))
if (myself->getsigmask () & (bit = SIGTOMASK (sig))) if (myself->getsigmask () & (bit = SIGTOMASK (pack.sig)))
*mask |= bit; *pack.mask |= bit;
break; break;
default: default:
if (sig < 0) if (pack.sig < 0)
sig_clear (-sig); sig_clear (-pack.sig);
else else
{ {
int sh; int sh;
for (int i = 0; !(sh = sig_handle (sig, *mask)) && i < 100 ; i++) for (int i = 0; !(sh = sig_handle (pack.sig, *pack.mask)) && i < 100 ; i++)
low_priority_sleep (0); // hopefully a temporary condition low_priority_sleep (0); // hopefully a temporary condition
if (sh <= 0) if (sh <= 0)
sigqueue.add (sig); // FIXME: Shouldn't add this in !sh condition sigqueue.add (pack.sig); // FIXME: Shouldn't add this in !sh condition
if (sig == SIGCHLD) if (pack.sig == SIGCHLD)
proc_subproc (PROC_CLEARWAIT, 0); proc_subproc (PROC_CLEARWAIT, 0);
} }
case __SIGFLUSH: case __SIGFLUSH:
sigqueue.reset (); sigqueue.reset ();
while ((sig = sigqueue.next ())) while ((pack.sig = sigqueue.next ()))
if (sig_handle (sig, *mask) > 0) if (sig_handle (pack.sig, *pack.mask) > 0)
sigqueue.del (); sigqueue.del ();
break; break;
} }
if (wakeup) if (pack.wakeup)
SetEvent (wakeup); SetEvent (pack.wakeup);
} }
sigproc_printf ("done"); sigproc_printf ("done");