* cygerrno.h (set_errno): Set global errno whenever setting thread specific
version. * debug.cc (__set_errno): Ditto. * exceptions.cc (handle_sigsuspend): Remove spurious sig_dispatch_pending call. (set_signal_mask): When there seem to be pending signals to dispatch, tell signal_dispatch_pending/sig_send not to specifically call any handlers. * sigproc.h (sig_dispatch_pending): Change declaration to void. * sigproc.cc (sig_dispatch_pending): Change definition to void. Take an argument to determine whether to tell sig_send to wait for handler to be called. * sigproc.cc (sig_send): Don't call signal handler when sig == __SIGFLUSHFAST. (wait_sig): Honor __SIGFLUSHFAST. Guard against sigpacket::process nuking si_signo. * sigproc.h (__SIGFLUSHFAST): Define new special signal. (sig_dispatch_pending): Change declaration to void. Take optional boolean argument. * fork.cc (vfork): Add debugging output.
This commit is contained in:
		| @@ -1,3 +1,28 @@ | |||||||
|  | 2004-02-01  Christopher Faylor  <cgf@redhat.com> | ||||||
|  |  | ||||||
|  | 	* cygerrno.h (set_errno): Set global errno whenever setting thread | ||||||
|  | 	specific version. | ||||||
|  | 	* debug.cc (__set_errno): Ditto. | ||||||
|  |  | ||||||
|  | 	* exceptions.cc (handle_sigsuspend): Remove spurious | ||||||
|  | 	sig_dispatch_pending call. | ||||||
|  | 	(set_signal_mask): When there seem to be pending signals to dispatch, | ||||||
|  | 	tell signal_dispatch_pending/sig_send not to specifically call any | ||||||
|  | 	handlers. | ||||||
|  | 	* sigproc.h (sig_dispatch_pending): Change declaration to void. | ||||||
|  | 	* sigproc.cc (sig_dispatch_pending): Change definition to void.  Take | ||||||
|  | 	an argument to determine whether to tell sig_send to wait for handler | ||||||
|  | 	to be called. | ||||||
|  | 	* sigproc.cc (sig_send): Don't call signal handler when sig == | ||||||
|  | 	__SIGFLUSHFAST. | ||||||
|  | 	(wait_sig): Honor __SIGFLUSHFAST.  Guard against sigpacket::process | ||||||
|  | 	nuking si_signo. | ||||||
|  | 	* sigproc.h (__SIGFLUSHFAST): Define new special signal. | ||||||
|  | 	(sig_dispatch_pending): Change declaration to void.  Take optional | ||||||
|  | 	boolean argument. | ||||||
|  |  | ||||||
|  | 	* fork.cc (vfork): Add debugging output. | ||||||
|  |  | ||||||
| 2004-01-26  Christopher Faylor  <cgf@redhat.com> | 2004-01-26  Christopher Faylor  <cgf@redhat.com> | ||||||
|  |  | ||||||
| 	* exceptions.cc (sig_handle_tty_stop): Avoid races by waiting for both | 	* exceptions.cc (sig_handle_tty_stop): Avoid races by waiting for both | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| /* cygerrno.h: main Cygwin header file. | /* cygerrno.h: main Cygwin header file. | ||||||
|  |  | ||||||
|    Copyright 2000, 2001, 2002, 2003 Red Hat, Inc. |    Copyright 2000, 2001, 2002, 2003, 2004 Red Hat, Inc. | ||||||
|  |  | ||||||
| This file is part of Cygwin. | This file is part of Cygwin. | ||||||
|  |  | ||||||
| @@ -18,7 +18,7 @@ int __stdcall geterrno_from_win_error (DWORD code, int deferrno) __attribute__ ( | |||||||
| #define __seterrno_from_win_error(val) seterrno_from_win_error (__FILE__, __LINE__, val) | #define __seterrno_from_win_error(val) seterrno_from_win_error (__FILE__, __LINE__, val) | ||||||
|  |  | ||||||
| #ifndef DEBUGGING | #ifndef DEBUGGING | ||||||
| #define set_errno(val) (errno = (val)) | #define set_errno(val) (errno = (val); _impure_ptr->_errno = (val)) | ||||||
| #else | #else | ||||||
| int __stdcall __set_errno (const char *ln, int ln, int val) __attribute ((regparm(3))); | int __stdcall __set_errno (const char *ln, int ln, int val) __attribute ((regparm(3))); | ||||||
| #define set_errno(val) __set_errno (__PRETTY_FUNCTION__, __LINE__, (val)) | #define set_errno(val) __set_errno (__PRETTY_FUNCTION__, __LINE__, (val)) | ||||||
|   | |||||||
| @@ -237,6 +237,7 @@ int __stdcall | |||||||
| __set_errno (const char *func, int ln, int val) | __set_errno (const char *func, int ln, int val) | ||||||
| { | { | ||||||
|   debug_printf ("%s:%d val %d", func, ln, val); |   debug_printf ("%s:%d val %d", func, ln, val); | ||||||
|  |   _impure_ptr->_errno = val; | ||||||
|   return errno = val; |   return errno = val; | ||||||
| } | } | ||||||
| #endif /*DEBUGGING*/ | #endif /*DEBUGGING*/ | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| /* exceptions.cc | /* exceptions.cc | ||||||
|  |  | ||||||
|    Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 Red Hat, Inc. |    Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Red Hat, Inc. | ||||||
|  |  | ||||||
| This file is part of Cygwin. | This file is part of Cygwin. | ||||||
|  |  | ||||||
| @@ -591,11 +591,10 @@ stack (void) | |||||||
| int __stdcall | int __stdcall | ||||||
| handle_sigsuspend (sigset_t tempmask) | handle_sigsuspend (sigset_t tempmask) | ||||||
| { | { | ||||||
|   sig_dispatch_pending (); |  | ||||||
|   sigset_t oldmask = myself->getsigmask ();	// Remember for restoration |   sigset_t oldmask = myself->getsigmask ();	// Remember for restoration | ||||||
|  |  | ||||||
|   set_signal_mask (tempmask &= ~SIG_NONMASKABLE, oldmask);// Let signals we're |   // Let signals we're interested in through. | ||||||
| 				//  interested in through. |   set_signal_mask (tempmask &= ~SIG_NONMASKABLE, oldmask); | ||||||
|   sigproc_printf ("oldmask %p, newmask %p", oldmask, tempmask); |   sigproc_printf ("oldmask %p, newmask %p", oldmask, tempmask); | ||||||
|  |  | ||||||
|   pthread_testcancel (); |   pthread_testcancel (); | ||||||
| @@ -925,11 +924,11 @@ set_signal_mask (sigset_t newmask, sigset_t oldmask) | |||||||
|   sigproc_printf ("oldmask %p, newmask %p, mask_bits %p", oldmask, newmask, |   sigproc_printf ("oldmask %p, newmask %p, mask_bits %p", oldmask, newmask, | ||||||
| 		  mask_bits); | 		  mask_bits); | ||||||
|   myself->setsigmask (newmask);	// Set a new mask |   myself->setsigmask (newmask);	// Set a new mask | ||||||
|   mask_sync->release (); |  | ||||||
|   if (mask_bits) |   if (mask_bits) | ||||||
|     sig_dispatch_pending (); |     sig_dispatch_pending (true); | ||||||
|   else |   else | ||||||
|     sigproc_printf ("not calling sig_dispatch_pending"); |     sigproc_printf ("not calling sig_dispatch_pending"); | ||||||
|  |   mask_sync->release (); | ||||||
|   return; |   return; | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -698,6 +698,7 @@ extern "C" int | |||||||
| vfork () | vfork () | ||||||
| { | { | ||||||
| #ifndef NEWVFORK | #ifndef NEWVFORK | ||||||
|  |   debug_printf ("stub called"); | ||||||
|   return fork (); |   return fork (); | ||||||
| #else | #else | ||||||
|   vfork_save *vf = get_vfork_val (); |   vfork_save *vf = get_vfork_val (); | ||||||
|   | |||||||
| @@ -63,7 +63,7 @@ public: | |||||||
|   sigpacket *next (); |   sigpacket *next (); | ||||||
|   sigpacket *save () const {return curr;} |   sigpacket *save () const {return curr;} | ||||||
|   void restore (sigpacket *saved) {curr = saved;} |   void restore (sigpacket *saved) {curr = saved;} | ||||||
|   friend int __stdcall sig_dispatch_pending (); |   friend void __stdcall sig_dispatch_pending (bool); | ||||||
| }; | }; | ||||||
|  |  | ||||||
| static pending_signals sigqueue; | static pending_signals sigqueue; | ||||||
| @@ -431,8 +431,7 @@ proc_subproc (DWORD what, DWORD val) | |||||||
|  |  | ||||||
|     scan_wait: |     scan_wait: | ||||||
|       /* Scan the linked list of wait()ing threads.  If a wait's parameters |       /* Scan the linked list of wait()ing threads.  If a wait's parameters | ||||||
|        * match this pid, then activate it. |          match this pid, then activate it.  */ | ||||||
|        */ |  | ||||||
|       for (w = &waitq_head; w->next != NULL; w = w->next) |       for (w = &waitq_head; w->next != NULL; w = w->next) | ||||||
| 	{ | 	{ | ||||||
| 	  if ((potential_match = checkstate (w)) > 0) | 	  if ((potential_match = checkstate (w)) > 0) | ||||||
| @@ -567,8 +566,8 @@ sigpending (sigset_t *mask) | |||||||
| } | } | ||||||
|  |  | ||||||
| /* Force the wait_sig thread to wake up and scan for pending signals */ | /* Force the wait_sig thread to wake up and scan for pending signals */ | ||||||
| int __stdcall | void __stdcall | ||||||
| sig_dispatch_pending () | sig_dispatch_pending (bool fast) | ||||||
| { | { | ||||||
|   if (exit_state || GetCurrentThreadId () == sigtid || !sigqueue.start.next) |   if (exit_state || GetCurrentThreadId () == sigtid || !sigqueue.start.next) | ||||||
|     { |     { | ||||||
| @@ -576,14 +575,13 @@ sig_dispatch_pending () | |||||||
|       sigproc_printf ("exit_state %d, cur thread id %p, sigtid %p, sigqueue.start.next %p", |       sigproc_printf ("exit_state %d, cur thread id %p, sigtid %p, sigqueue.start.next %p", | ||||||
| 		      exit_state, GetCurrentThreadId (), sigtid, sigqueue.start.next); | 		      exit_state, GetCurrentThreadId (), sigtid, sigqueue.start.next); | ||||||
| #endif | #endif | ||||||
|       return 0; |       return; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| #ifdef DEBUGGING | #ifdef DEBUGGING | ||||||
|   sigproc_printf ("flushing"); |   sigproc_printf ("flushing"); | ||||||
| #endif | #endif | ||||||
|   (void) sig_send (myself, __SIGFLUSH); |   (void) sig_send (myself, fast ? __SIGFLUSHFAST : __SIGFLUSH); | ||||||
|   return call_signal_handler_now (); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| /* Message initialization.  Called from dll_crt0_1 | /* Message initialization.  Called from dll_crt0_1 | ||||||
| @@ -800,6 +798,12 @@ sig_send (_pinfo *p, siginfo_t& si, _threadinfo *tls) | |||||||
| 	ForceCloseHandle (sendsig); | 	ForceCloseHandle (sendsig); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |   if (pack.wakeup) | ||||||
|  |     { | ||||||
|  |       ForceCloseHandle (pack.wakeup); | ||||||
|  |       pack.wakeup = NULL; | ||||||
|  |     } | ||||||
|  |  | ||||||
|   if (rc == WAIT_OBJECT_0) |   if (rc == WAIT_OBJECT_0) | ||||||
|     rc = 0;		// Successful exit |     rc = 0;		// Successful exit | ||||||
|   else |   else | ||||||
| @@ -811,13 +815,12 @@ sig_send (_pinfo *p, siginfo_t& si, _threadinfo *tls) | |||||||
|       rc = -1; |       rc = -1; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   if (wait_for_completion) |   if (wait_for_completion && si.si_signo != __SIGFLUSHFAST) | ||||||
|     call_signal_handler_now (); |     call_signal_handler_now (); | ||||||
|  |  | ||||||
| out: | out: | ||||||
|   if (pack.wakeup) |   if (pack.wakeup) | ||||||
|     ForceCloseHandle (pack.wakeup); |     ForceCloseHandle (pack.wakeup); | ||||||
|  |  | ||||||
|   if (si.si_signo != __SIGPENDING) |   if (si.si_signo != __SIGPENDING) | ||||||
|     /* nothing */; |     /* nothing */; | ||||||
|   else if (!rc) |   else if (!rc) | ||||||
| @@ -1164,6 +1167,7 @@ wait_sig (VOID *self) | |||||||
| 	      *pack.mask |= bit; | 	      *pack.mask |= bit; | ||||||
| 	  break; | 	  break; | ||||||
| 	case __SIGFLUSH: | 	case __SIGFLUSH: | ||||||
|  | 	case __SIGFLUSHFAST: | ||||||
| 	  sigqueue.reset (); | 	  sigqueue.reset (); | ||||||
| 	  while ((q = sigqueue.next ())) | 	  while ((q = sigqueue.next ())) | ||||||
| 	    if (q->si.si_signo == __SIGDELETE || q->process () > 0) | 	    if (q->si.si_signo == __SIGDELETE || q->process () > 0) | ||||||
| @@ -1174,6 +1178,7 @@ wait_sig (VOID *self) | |||||||
| 	    sig_clear (-pack.si.si_signo); | 	    sig_clear (-pack.si.si_signo); | ||||||
| 	  else | 	  else | ||||||
| 	    { | 	    { | ||||||
|  | 	      int sig = pack.si.si_signo; | ||||||
| 	      int sigres = pack.process (); | 	      int sigres = pack.process (); | ||||||
| 	      if (sigres <= 0) | 	      if (sigres <= 0) | ||||||
| 		{ | 		{ | ||||||
| @@ -1183,7 +1188,7 @@ wait_sig (VOID *self) | |||||||
| #endif | #endif | ||||||
| 		  sigqueue.add (pack);	// FIXME: Shouldn't add this in !sh condition | 		  sigqueue.add (pack);	// FIXME: Shouldn't add this in !sh condition | ||||||
| 		} | 		} | ||||||
| 	      if (pack.si.si_signo == SIGCHLD) | 	      if (sig == SIGCHLD) | ||||||
| 		proc_subproc (PROC_CLEARWAIT, 0); | 		proc_subproc (PROC_CLEARWAIT, 0); | ||||||
| 	    } | 	    } | ||||||
| 	  break; | 	  break; | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| /* sigproc.h | /* sigproc.h | ||||||
|  |  | ||||||
|    Copyright 1997, 1998, 2000, 2001, 2002, 2003 Red Hat, Inc. |    Copyright 1997, 1998, 2000, 2001, 2002, 2003, 2004 Red Hat, Inc. | ||||||
|  |  | ||||||
| This file is part of Cygwin. | This file is part of Cygwin. | ||||||
|  |  | ||||||
| @@ -23,7 +23,8 @@ enum | |||||||
|   __SIGSTRACE	    = -(NSIG + 2), |   __SIGSTRACE	    = -(NSIG + 2), | ||||||
|   __SIGCOMMUNE	    = -(NSIG + 3), |   __SIGCOMMUNE	    = -(NSIG + 3), | ||||||
|   __SIGPENDING	    = -(NSIG + 4), |   __SIGPENDING	    = -(NSIG + 4), | ||||||
|   __SIGDELETE	    = -(NSIG + 5) |   __SIGDELETE	    = -(NSIG + 5), | ||||||
|  |   __SIGFLUSHFAST    = -(NSIG + 6) | ||||||
| }; | }; | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
| @@ -67,7 +68,7 @@ extern HANDLE signal_arrived; | |||||||
| extern HANDLE sigCONT; | extern HANDLE sigCONT; | ||||||
|  |  | ||||||
| bool __stdcall my_parent_is_alive (); | bool __stdcall my_parent_is_alive (); | ||||||
| int __stdcall sig_dispatch_pending (); | void __stdcall sig_dispatch_pending (bool fast = false); | ||||||
| #ifdef _PINFO_H | #ifdef _PINFO_H | ||||||
| extern "C" void __stdcall set_signal_mask (sigset_t newmask, sigset_t = myself->getsigmask ()); | extern "C" void __stdcall set_signal_mask (sigset_t newmask, sigset_t = myself->getsigmask ()); | ||||||
| #endif | #endif | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user