diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 8ae49e643..85f9f7043 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,7 +1,26 @@ +2003-08-19 Christopher Faylor + + Throughout, eliminate argument to sig_dispatch_pending. + * exceptions.cc (setup_handler): Move non-interruptible condition + handling (back) to wait_sig (as suggested by Pierre Humblet). + (set_process_mask): Don't worry about calling sig_dispatch_pending from + sigthread since it is detected in the function anyway. + (sig_handle): Eliminate thisproc arg. Don't call sig_dispatch_pending + on SIGCONT since that should happen automatically. + * sigproc.cc (sig_dispatch_pending): Eliminate justwake argument. Just + return when called from sigthread. + (wait_sig): Change some variables to bool. Change inner while to an + if. Move uninterruptible signal handling here. + (sigproc_terminate): Don't call sig_dispatch_pending. Just increment + semaphore on exit. + + * speclib: Use slightly different (but still flawed) method for + determining symbols to extract from libraries. + 2003-08-18 Christopher Faylor * exceptions.cc (sigdelayed): Fix race where signal handler could get - the wrong mask. + the wrong mask (as suggested by Pierre Humblet). 2003-08-18 Christopher Faylor diff --git a/winsup/cygwin/exceptions.cc b/winsup/cygwin/exceptions.cc index b330a29b2..dea7c8b3e 100644 --- a/winsup/cygwin/exceptions.cc +++ b/winsup/cygwin/exceptions.cc @@ -569,7 +569,7 @@ stack (void) int __stdcall handle_sigsuspend (sigset_t tempmask) { - sig_dispatch_pending (0); + sig_dispatch_pending (); sigframe thisframe (mainthread); sigset_t oldmask = myself->getsigmask (); // Remember for restoration @@ -901,14 +901,6 @@ setup_handler (int sig, void *handler, struct sigaction& siga) SetThreadPriority (GetCurrentThread (), WAIT_SIG_PRIORITY); sigproc_printf ("signal successfully delivered"); } - else - { - pending_signals = 1; /* FIXME: Probably need to be more tricky here */ - sig_set_pending (sig); - sig_dispatch_pending (1); - low_priority_sleep (SLEEP_0_STAY_LOW); /* Hopefully, other process will be waking up soon. */ - sigproc_printf ("couldn't send signal %d", sig); - } sigproc_printf ("returning %d", interrupted); return interrupted; @@ -990,7 +982,7 @@ set_process_mask (sigset_t newmask) sigproc_printf ("old mask = %x, new mask = %x", myself->getsigmask (), newmask); myself->setsigmask (newmask); // Set a new mask mask_sync->release (); - if (oldmask != newmask && GetCurrentThreadId () != sigtid) + if (oldmask != newmask) sig_dispatch_pending (); else sigproc_printf ("not calling sig_dispatch_pending. sigtid %p current %p", @@ -999,7 +991,7 @@ set_process_mask (sigset_t newmask) } int __stdcall -sig_handle (int sig, bool thisproc) +sig_handle (int sig) { int rc = 0; @@ -1034,7 +1026,9 @@ sig_handle (int sig, bool thisproc) if (stopped) SetEvent (sigCONT); /* process pending signals */ - sig_dispatch_pending (1); +#if 0 // FIXME? + sig_dispatch_pending (); +#endif } #if 0 @@ -1046,7 +1040,7 @@ sig_handle (int sig, bool thisproc) if (handler == (void *) SIG_DFL) { if (sig == SIGCHLD || sig == SIGIO || sig == SIGCONT || sig == SIGWINCH - || sig == SIGURG || (thisproc && hExeced && sig == SIGINT)) + || sig == SIGURG || (hExeced && sig == SIGINT)) { sigproc_printf ("default signal %d ignored", sig); goto done; diff --git a/winsup/cygwin/net.cc b/winsup/cygwin/net.cc index 3db52f883..36463c3b4 100644 --- a/winsup/cygwin/net.cc +++ b/winsup/cygwin/net.cc @@ -583,7 +583,7 @@ cygwin_sendto (int fd, const void *buf, int len, int flags, const struct sockaddr *to, int tolen) { int res; - sig_dispatch_pending (0); + sig_dispatch_pending (); sigframe thisframe (mainthread); fhandler_socket *fh = get (fd); @@ -607,7 +607,7 @@ cygwin_recvfrom (int fd, void *buf, int len, int flags, struct sockaddr *from, int *fromlen) { int res; - sig_dispatch_pending (0); + sig_dispatch_pending (); sigframe thisframe (mainthread); fhandler_socket *fh = get (fd); @@ -764,7 +764,7 @@ extern "C" int cygwin_connect (int fd, const struct sockaddr *name, int namelen) { int res; - sig_dispatch_pending (0); + sig_dispatch_pending (); sigframe thisframe (mainthread); fhandler_socket *fh = get (fd); @@ -903,7 +903,7 @@ static struct servent *servent_buf = NULL; extern "C" struct servent * cygwin_getservbyname (const char *name, const char *proto) { - sig_dispatch_pending (0); + sig_dispatch_pending (); sigframe thisframe (mainthread); if (check_null_str_errno (name) || (proto != NULL && check_null_str_errno (proto))) @@ -922,7 +922,7 @@ cygwin_getservbyname (const char *name, const char *proto) extern "C" struct servent * cygwin_getservbyport (int port, const char *proto) { - sig_dispatch_pending (0); + sig_dispatch_pending (); sigframe thisframe (mainthread); if (proto != NULL && check_null_str_errno (proto)) return NULL; @@ -939,7 +939,7 @@ cygwin_getservbyport (int port, const char *proto) extern "C" int cygwin_gethostname (char *name, size_t len) { - sig_dispatch_pending (0); + sig_dispatch_pending (); sigframe thisframe (mainthread); if (__check_null_invalid_struct_errno (name, len)) return -1; @@ -1023,7 +1023,7 @@ cygwin_gethostbyname (const char *name) static char *tmp_addr_list[2]; static int a, b, c, d; - sig_dispatch_pending (0); + sig_dispatch_pending (); sigframe thisframe (mainthread); if (check_null_str_errno (name)) return NULL; @@ -1064,7 +1064,7 @@ cygwin_gethostbyname (const char *name) extern "C" struct hostent * cygwin_gethostbyaddr (const char *addr, int len, int type) { - sig_dispatch_pending (0); + sig_dispatch_pending (); sigframe thisframe (mainthread); if (__check_invalid_read_ptr_errno (addr, len)) return NULL; @@ -1089,7 +1089,7 @@ extern "C" int cygwin_accept (int fd, struct sockaddr *peer, int *len) { int res; - sig_dispatch_pending (0); + sig_dispatch_pending (); sigframe thisframe (mainthread); fhandler_socket *fh = get (fd); @@ -1122,7 +1122,7 @@ extern "C" int cygwin_bind (int fd, const struct sockaddr *my_addr, int addrlen) { int res; - sig_dispatch_pending (0); + sig_dispatch_pending (); sigframe thisframe (mainthread); fhandler_socket *fh = get (fd); @@ -1140,7 +1140,7 @@ extern "C" int cygwin_getsockname (int fd, struct sockaddr *addr, int *namelen) { int res; - sig_dispatch_pending (0); + sig_dispatch_pending (); sigframe thisframe (mainthread); fhandler_socket *fh = get (fd); @@ -1161,7 +1161,7 @@ extern "C" int cygwin_listen (int fd, int backlog) { int res; - sig_dispatch_pending (0); + sig_dispatch_pending (); sigframe thisframe (mainthread); fhandler_socket *fh = get (fd); @@ -1179,7 +1179,7 @@ extern "C" int cygwin_shutdown (int fd, int how) { int res; - sig_dispatch_pending (0); + sig_dispatch_pending (); sigframe thisframe (mainthread); fhandler_socket *fh = get (fd); @@ -1245,7 +1245,7 @@ extern "C" int cygwin_getpeername (int fd, struct sockaddr *name, int *len) { int res; - sig_dispatch_pending (0); + sig_dispatch_pending (); sigframe thisframe (mainthread); fhandler_socket *fh = get (fd); @@ -1286,7 +1286,7 @@ getdomainname (char *domain, size_t len) * in use and include paths for the Domain name in each ? * Punt for now and assume MS-TCP on Win95. */ - sig_dispatch_pending (0); + sig_dispatch_pending (); sigframe thisframe (mainthread); if (__check_null_invalid_struct_errno (domain, len)) return -1; @@ -1900,7 +1900,7 @@ get_ifconf (struct ifconf *ifc, int what) unsigned long lip, lnp; struct sockaddr_in *sa; - sig_dispatch_pending (0); + sig_dispatch_pending (); sigframe thisframe (mainthread); if (check_null_invalid_struct_errno (ifc)) return -1; @@ -1979,7 +1979,7 @@ cygwin_rcmd (char **ahost, unsigned short inport, char *locuser, int res = -1; SOCKET fd2s; - sig_dispatch_pending (0); + sig_dispatch_pending (); sigframe thisframe (mainthread); if (check_null_invalid_struct_errno (ahost) || @@ -2037,7 +2037,7 @@ extern "C" int cygwin_rresvport (int *port) { int res; - sig_dispatch_pending (0); + sig_dispatch_pending (); sigframe thisframe (mainthread); if (check_null_invalid_struct_errno (port)) @@ -2069,7 +2069,7 @@ cygwin_rexec (char **ahost, unsigned short inport, char *locuser, { int res = -1; SOCKET fd2s; - sig_dispatch_pending (0); + sig_dispatch_pending (); sigframe thisframe (mainthread); if (check_null_invalid_struct_errno (ahost) || @@ -2132,7 +2132,7 @@ socketpair (int family, int type, int protocol, int *sb) struct sockaddr_in sock_in, sock_out; int len; - sig_dispatch_pending (0); + sig_dispatch_pending (); sigframe thisframe (mainthread); if (__check_null_invalid_struct_errno (sb, 2 * sizeof (int))) return -1; @@ -2333,7 +2333,7 @@ extern "C" int cygwin_recvmsg (int fd, struct msghdr *msg, int flags) { int res; - sig_dispatch_pending (0); + sig_dispatch_pending (); sigframe thisframe (mainthread); fhandler_socket *fh = get (fd); @@ -2360,7 +2360,7 @@ extern "C" int cygwin_sendmsg (int fd, const struct msghdr *msg, int flags) { int res; - sig_dispatch_pending (0); + sig_dispatch_pending (); sigframe thisframe (mainthread); fhandler_socket *fh = get (fd); diff --git a/winsup/cygwin/signal.cc b/winsup/cygwin/signal.cc index 0530fcf47..09dcbca51 100644 --- a/winsup/cygwin/signal.cc +++ b/winsup/cygwin/signal.cc @@ -42,7 +42,7 @@ set_sigcatchers (void (*oldsig) (int), void (*cursig) (int)) extern "C" _sig_func_ptr signal (int sig, _sig_func_ptr func) { - sig_dispatch_pending (0); + sig_dispatch_pending (); _sig_func_ptr prev; /* check that sig is in right range */ @@ -69,7 +69,7 @@ extern "C" int nanosleep (const struct timespec *rqtp, struct timespec *rmtp) { int res = 0; - sig_dispatch_pending (0); + sig_dispatch_pending (); sigframe thisframe (mainthread); pthread_testcancel (); @@ -127,7 +127,7 @@ usleep (unsigned int useconds) extern "C" int sigprocmask (int sig, const sigset_t *set, sigset_t *oldset) { - sig_dispatch_pending (0); + sig_dispatch_pending (); /* check that sig is in right range */ if (sig < 0 || sig >= NSIG) { @@ -167,7 +167,7 @@ sigprocmask (int sig, const sigset_t *set, sigset_t *oldset) static int kill_worker (pid_t pid, int sig) { - sig_dispatch_pending (0); + sig_dispatch_pending (); int res = 0; pinfo dest (pid); @@ -287,7 +287,7 @@ killpg (pid_t pgrp, int sig) extern "C" void abort (void) { - sig_dispatch_pending (0); + sig_dispatch_pending (); sigframe thisframe (mainthread); /* Flush all streams as per SUSv2. From my reading of this document, this isn't strictly correct. @@ -313,7 +313,7 @@ abort (void) extern "C" int sigaction (int sig, const struct sigaction *newact, struct sigaction *oldact) { - sig_dispatch_pending (0); + sig_dispatch_pending (); sigproc_printf ("signal %d, newact %p, oldact %p", sig, newact, oldact); /* check that sig is in right range */ if (sig < 0 || sig >= NSIG) diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc index 34492a9ee..ae9c3302a 100644 --- a/winsup/cygwin/sigproc.cc +++ b/winsup/cygwin/sigproc.cc @@ -514,22 +514,19 @@ sig_clear (int sig) /* Force the wait_sig thread to wake up and scan the sigtodo array. */ extern "C" int __stdcall -sig_dispatch_pending (int justwake) +sig_dispatch_pending () { - if (!hwait_sig) + if (!hwait_sig || GetCurrentThreadId () == sigtid) return 0; - DWORD tid = GetCurrentThreadId (); sigframe thisframe (mainthread); - if (tid == sigtid && !justwake) - justwake = 1; - int was_pending = pending_signals; #ifdef DEBUGGING sigproc_printf ("pending_signals %d", was_pending); #endif - if (!was_pending && !justwake) + + if (!was_pending) #ifdef DEBUGGING sigproc_printf ("no need to wake anything up"); #else @@ -537,21 +534,13 @@ sig_dispatch_pending (int justwake) #endif else { - if (!justwake) - (void) sig_send (myself, __SIGFLUSH); - else if (ReleaseSemaphore (sigcatch_nosync, 1, NULL)) + (void) sig_send (myself, __SIGFLUSH); #ifdef DEBUGGING - sigproc_printf ("woke up wait_sig"); -#else - ; + sigproc_printf ("woke up wait_sig"); #endif - else if (no_signals_available ()) - /*sigproc_printf ("I'm going away now")*/; - else - system_printf ("%E releasing sigcatch_nosync(%p)", sigcatch_nosync); - } - if (was_pending && !justwake) + + if (was_pending) thisframe.call_signal_handler (); return was_pending; @@ -614,11 +603,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 (1); - } - - if (GetCurrentThreadId () == sigtid) - { ForceCloseHandle (sigcomplete_main); for (int i = 0; i < 20; i++) (void) ReleaseSemaphore (sigcomplete_nonmain, 1, NULL); @@ -1132,14 +1116,20 @@ wait_sig (VOID *self) * array looking for any unprocessed signals. */ pending_signals = -1; - int saw_pending_signals = 0; - int saw_sigchld = 0; + bool saw_pending_signals = false; + bool saw_sigchld = false; for (int sig = -__SIGOFFSET; sig < NSIG; sig++) { - while (InterlockedDecrement (myself->getsigtodo (sig)) >= 0) + LONG x = InterlockedDecrement (myself->getsigtodo (sig)); + if (x < 0) + InterlockedIncrement (myself->getsigtodo (sig)); + else if (x >= 0) { + if (x > 0) + pending_signals = 1; + if (sig == SIGCHLD) - saw_sigchld = 1; + saw_sigchld = true; if (sig > 0 && sig != SIGKILL && sig != SIGSTOP && (sigismember (&myself->getsigmask (), sig) || @@ -1147,44 +1137,47 @@ wait_sig (VOID *self) (sig != SIGCONT && ISSTATE (myself, PID_STOPPED)))) { sigproc_printf ("signal %d blocked", sig); - break; + InterlockedIncrement (myself->getsigtodo (sig)); } - - /* Found a signal to process */ - sigproc_printf ("processing signal %d", sig); - switch (sig) + else { - case __SIGFLUSH: - /* just forcing the loop */ - break; + /* Found a signal to process */ + sigproc_printf ("processing signal %d", sig); + switch (sig) + { + case __SIGFLUSH: + /* just forcing the loop */ + break; - /* Internal signal to turn on stracing. */ - case __SIGSTRACE: - strace.hello (); - break; + /* Internal signal to turn on stracing. */ + case __SIGSTRACE: + strace.hello (); + break; - case __SIGCOMMUNE: - talktome (); - break; + case __SIGCOMMUNE: + talktome (); + break; - /* A normal UNIX signal */ - default: - sigproc_printf ("Got signal %d", sig); - sig_handle (sig, rc != 2); - /* Need to decrement again to offset increment below since - we really do want to decrement in this case. */ - InterlockedDecrement (myself->getsigtodo (sig)); - goto nextsig; /* FIXME: shouldn't this allow the loop to continue? */ + /* A normal UNIX signal */ + default: + sigproc_printf ("Got signal %d", sig); + if (!sig_handle (sig)) + { + sigproc_printf ("couldn't send signal %d", sig); + low_priority_sleep (SLEEP_0_STAY_LOW); /* Hopefully, other process will be waking up soon. */ + saw_pending_signals = true; + ReleaseSemaphore (sigcatch_nosync, 1, NULL); + InterlockedIncrement (myself->getsigtodo (sig)); + } + break; + } } } - - nextsig: - /* Decremented too far. */ - if (InterlockedIncrement (myself->getsigtodo (sig)) > 0) - saw_pending_signals = 1; } - if (pending_signals < 0 && !saw_pending_signals) + if (saw_pending_signals) + pending_signals = 1; + else if (pending_signals < 0) pending_signals = 0; if (saw_sigchld) diff --git a/winsup/cygwin/sigproc.h b/winsup/cygwin/sigproc.h index cda8cad67..d3061bc50 100644 --- a/winsup/cygwin/sigproc.h +++ b/winsup/cygwin/sigproc.h @@ -98,10 +98,10 @@ extern HANDLE signal_arrived; extern HANDLE sigCONT; BOOL __stdcall my_parent_is_alive (); -extern "C" int __stdcall sig_dispatch_pending (int force = FALSE); +extern "C" int __stdcall sig_dispatch_pending (); extern "C" void __stdcall set_process_mask (sigset_t newmask); extern "C" void __stdcall reset_signal_arrived (); -int __stdcall sig_handle (int, bool); +int __stdcall sig_handle (int); void __stdcall sig_clear (int); void __stdcall sig_set_pending (int); int __stdcall handle_sigsuspend (sigset_t); diff --git a/winsup/cygwin/speclib b/winsup/cygwin/speclib index 69074096c..c686343ad 100755 --- a/winsup/cygwin/speclib +++ b/winsup/cygwin/speclib @@ -18,8 +18,8 @@ nm=$1; shift ar=$1; shift libdll=$1; shift cp /dev/null /tmp/$$.objs -trap "/bin/rm -rf /tmp/$$.dir /tmp/$$.syms /tmp/$$.objs /tmp/$$.raw" 0 1 2 15 -$nm --extern-only --defined-only $* | sed -e '/^[ ]*$/d' -e '/:$/d' -e 's%^.* _\(.*\)%/ __imp__\1$/p%' | grep -v ' __imp___imp__' > /tmp/$$.syms +# trap "/bin/rm -rf /tmp/$$.dir /tmp/$$.syms /tmp/$$.objs /tmp/$$.raw" 0 1 2 15 +$nm --extern-only --defined-only $* | sed -n -e 's%^.* [TD] \(.*\)$%/ \1\$/p%p' > /tmp/$$.syms v || $nm -Ap --extern-only --defined-only $libdll | egrep ' I __head| I _.*_iname' | awk -F: '{print $2}' > /tmp/$$.objs $nm -Ap --extern-only --defined-only $libdll | sed -n -f /tmp/$$.syms | awk -F: '{print $2}' >> /tmp/$$.objs sort -o /tmp/$$.objs -u /tmp/$$.objs diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index f2e79760e..dedab012e 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -369,7 +369,7 @@ readv (int fd, const struct iovec *const iov, const int iovcnt) while (1) { - sig_dispatch_pending (0); + sig_dispatch_pending (); sigframe thisframe (mainthread); cygheap_fdget cfd (fd); @@ -441,7 +441,7 @@ extern "C" ssize_t writev (const int fd, const struct iovec *const iov, const int iovcnt) { int res = -1; - sig_dispatch_pending (0); + sig_dispatch_pending (); const ssize_t tot = check_iovec_for_write (iov, iovcnt); sigframe thisframe (mainthread); @@ -497,7 +497,7 @@ open (const char *unix_path, int flags, ...) int res = -1; va_list ap; mode_t mode = 0; - sig_dispatch_pending (0); + sig_dispatch_pending (); sigframe thisframe (mainthread); syscall_printf ("open (%s, %p)", unix_path, flags); diff --git a/winsup/cygwin/wait.cc b/winsup/cygwin/wait.cc index fd782783e..759afed25 100644 --- a/winsup/cygwin/wait.cc +++ b/winsup/cygwin/wait.cc @@ -54,7 +54,7 @@ wait4 (int intpid, int *status, int options, struct rusage *r) while (1) { - sig_dispatch_pending (0); + sig_dispatch_pending (); sigframe thisframe (mainthread); sawsig = 0; if (options & ~(WNOHANG | WUNTRACED))