* cygwait.cc (cancelable_wait): Add some debugging-only output.
* exceptions.cc (sig_handle_tty_stop): Make sure that incyg is cleared when exiting if we have no parent process. Only wait for signal_arrived. (sigpacket::process): Make continue_now a bool. Delay sending signal_arrived until the end. Make code more defensive to avoid calling signal handler when stopped. Only set signal_arrived when stopped. * sigproc.cc (sig_hold): Rename from sigCONT. Make static. (sig_send): Accommodate sigCONT -> sig_hold rename. (wait_sig): Ditto. * sigproc.h (sigCONT): Delete declaration. * fhandler_console.cc (fhandler_console::write): Use new '%0c' facility to print characters. Change to paranoid to avoid excessive strace output. * fhandler_tty.cc (fhandler_pty_master::accept_input): Make frequent strace printf "paranoid" to help cut down on strace output size. * signal.cc (sigsuspend): Add standard syscall strace output. (sigpause): Ditto. (pause): Ditto. * cygtls.h (_cygtls::reset_signal_arrived): New function.
This commit is contained in:
		| @@ -1,6 +1,30 @@ | ||||
| 2012-07-29  Christopher Faylor  <me.cygwin2012@cgf.cx> | ||||
|  | ||||
| 	* cygtls.cc (_cygtls::reset_signal_arrived): New function. | ||||
| 	* cygwait.cc (cancelable_wait): Add some debugging-only output. | ||||
| 	* exceptions.cc (sig_handle_tty_stop): Make sure that incyg is cleared | ||||
| 	when exiting if we have no parent process.  Only wait for signal_arrived. | ||||
| 	(sigpacket::process): Make continue_now a bool.  Delay sending | ||||
| 	signal_arrived until the end.  Make code more defensive to avoid | ||||
| 	calling signal handler when stopped.  Only set signal_arrived when | ||||
| 	stopped. | ||||
| 	* sigproc.cc (sig_hold): Rename from sigCONT.  Make static. | ||||
| 	(sig_send): Accommodate sigCONT -> sig_hold rename. | ||||
| 	(wait_sig): Ditto. | ||||
| 	* sigproc.h (sigCONT): Delete declaration. | ||||
|  | ||||
| 	* fhandler_console.cc (fhandler_console::write): Use new '%0c' facility | ||||
| 	to print characters.  Change to paranoid to avoid excessive strace | ||||
| 	output. | ||||
| 	* fhandler_tty.cc (fhandler_pty_master::accept_input): Make frequent | ||||
| 	strace printf "paranoid" to help cut down on strace output size. | ||||
|  | ||||
| 	* signal.cc (sigsuspend): Add standard syscall strace output. | ||||
| 	(sigpause): Ditto. | ||||
| 	(pause): Ditto. | ||||
|  | ||||
| 2012-07-29  Christopher Faylor  <me.cygwin2012@cgf.cx> | ||||
|  | ||||
| 	* cygtls.h (_cygtls::reset_signal_arrived): New function. | ||||
| 	(set_signal_arrived::~set_signal_arrived): Use reset_signal_arrived to | ||||
| 	reset state. | ||||
| 	* exceptions.cc (sig_handle_tty_stop): Use WAIT_SIGNALED rather than | ||||
|   | ||||
| @@ -39,7 +39,7 @@ cancelable_wait (HANDLE object, PLARGE_INTEGER timeout, unsigned mask) | ||||
|     wait_objects[num++] = object; | ||||
|  | ||||
|   set_signal_arrived thread_waiting (is_cw_sig_handle, wait_objects[num]); | ||||
| debug_printf ("thread waiting %d, signal_arrived %p", (int) thread_waiting, _my_tls.signal_arrived); | ||||
|   debug_only_printf ("object %p, thread waiting %d, signal_arrived %p", object, (int) thread_waiting, _my_tls.signal_arrived); | ||||
|   DWORD sig_n; | ||||
|   if (!thread_waiting) | ||||
|     sig_n = WAIT_TIMEOUT + 1; | ||||
| @@ -72,6 +72,7 @@ debug_printf ("thread waiting %d, signal_arrived %p", (int) thread_waiting, _my_ | ||||
|   while (1) | ||||
|     { | ||||
|       res = WaitForMultipleObjects (num, wait_objects, FALSE, INFINITE); | ||||
|       debug_only_printf ("res %d", res); | ||||
|       if (res == cancel_n) | ||||
| 	res = WAIT_CANCELED; | ||||
|       else if (res == timeout_n) | ||||
|   | ||||
| @@ -735,30 +735,29 @@ sig_handle_tty_stop (int sig) | ||||
|   /* Silently ignore attempts to suspend if there is no accommodating | ||||
|      cygwin parent to deal with this behavior. */ | ||||
|   if (!myself->cygstarted) | ||||
|     myself->process_state &= ~PID_STOPPED; | ||||
|   else | ||||
|     { | ||||
|       myself->process_state &= ~PID_STOPPED; | ||||
|       return; | ||||
|     } | ||||
|  | ||||
|   myself->stopsig = sig; | ||||
|   myself->alert_parent (sig); | ||||
|   sigproc_printf ("process %d stopped by signal %d", myself->pid, sig); | ||||
|   HANDLE w4[2]; | ||||
|   w4[0] = sigCONT; | ||||
|   switch (cancelable_wait (sigCONT, cw_infinite, cw_sig_eintr)) | ||||
|     { | ||||
|     case WAIT_OBJECT_0: | ||||
|     case WAIT_SIGNALED: | ||||
|       myself->stopsig = SIGCONT; | ||||
|       myself->alert_parent (SIGCONT); | ||||
|       break; | ||||
|     default: | ||||
|       api_fatal ("WaitSingleObject failed, %E"); | ||||
|       break; | ||||
|       myself->stopsig = sig; | ||||
|       myself->alert_parent (sig); | ||||
|       sigproc_printf ("process %d stopped by signal %d", myself->pid, sig); | ||||
|       /* FIXME! This does nothing to suspend anything other than the main | ||||
| 	 thread. */ | ||||
|       DWORD res = cancelable_wait (NULL, cw_infinite, cw_sig_eintr); | ||||
|       switch (res) | ||||
| 	{ | ||||
| 	case WAIT_SIGNALED: | ||||
| 	  myself->stopsig = SIGCONT; | ||||
| 	  myself->alert_parent (SIGCONT); | ||||
| 	  break; | ||||
| 	default: | ||||
| 	  api_fatal ("WaitSingleObject returned %d", res); | ||||
| 	  break; | ||||
| 	} | ||||
|     } | ||||
|   _my_tls.incyg = 0; | ||||
| } | ||||
| } | ||||
| } /* end extern "C" */ | ||||
|  | ||||
| bool | ||||
| _cygtls::interrupt_now (CONTEXT *cx, int sig, void *handler, | ||||
| @@ -1122,14 +1121,14 @@ set_signal_mask (sigset_t& setmask, sigset_t newmask) | ||||
| int __stdcall | ||||
| sigpacket::process () | ||||
| { | ||||
|   DWORD continue_now; | ||||
|   bool continue_now; | ||||
|   struct sigaction dummy = global_sigs[SIGSTOP]; | ||||
|  | ||||
|   if (si.si_signo != SIGCONT) | ||||
|     continue_now = false; | ||||
|   else | ||||
|     { | ||||
|       continue_now = myself->process_state & PID_STOPPED; | ||||
|       continue_now = ISSTATE (myself, PID_STOPPED); | ||||
|       myself->stopsig = 0; | ||||
|       myself->process_state &= ~PID_STOPPED; | ||||
|       /* Clear pending stop signals */ | ||||
| @@ -1206,9 +1205,7 @@ sigpacket::process () | ||||
|       if (si.si_signo == SIGCHLD || si.si_signo == SIGIO || si.si_signo == SIGCONT || si.si_signo == SIGWINCH | ||||
| 	  || si.si_signo == SIGURG) | ||||
| 	{ | ||||
| 	  sigproc_printf ("default signal %d ignored", si.si_signo); | ||||
| 	  if (continue_now) | ||||
| 	    SetEvent (tls->signal_arrived); | ||||
| 	  sigproc_printf ("signal %d default is currently ignore", si.si_signo); | ||||
| 	  goto done; | ||||
| 	} | ||||
|  | ||||
| @@ -1224,21 +1221,24 @@ sigpacket::process () | ||||
|   goto dosig; | ||||
|  | ||||
| stop: | ||||
|   /* Eat multiple attempts to STOP */ | ||||
|   if (ISSTATE (myself, PID_STOPPED)) | ||||
|     goto done; | ||||
|   handler = (void *) sig_handle_tty_stop; | ||||
|   thissig = dummy; | ||||
|  | ||||
| dosig: | ||||
|   tls->set_siginfo (this); | ||||
|   /* Dispatch to the appropriate function. */ | ||||
|   sigproc_printf ("signal %d, signal handler %p", si.si_signo, handler); | ||||
|   rc = setup_handler (si.si_signo, handler, thissig, tls); | ||||
|   if (ISSTATE (myself, PID_STOPPED) && !continue_now) | ||||
|       rc = -1;		/* No signals delivered if stopped */ | ||||
|   else | ||||
|     { | ||||
|       tls->set_siginfo (this); | ||||
|       /* Dispatch to the appropriate function. */ | ||||
|       sigproc_printf ("signal %d, signal handler %p", si.si_signo, handler); | ||||
|       rc = setup_handler (si.si_signo, handler, thissig, tls); | ||||
|       continue_now = false; | ||||
|     } | ||||
|  | ||||
| done: | ||||
|   if (continue_now) | ||||
|     SetEvent (sigCONT); | ||||
|     SetEvent (tls->signal_arrived); | ||||
|   sigproc_printf ("returning %d", rc); | ||||
|   return rc; | ||||
|  | ||||
|   | ||||
| @@ -2012,8 +2012,7 @@ fhandler_console::write (const void *vsrc, size_t len) | ||||
|  | ||||
|   while (src < end) | ||||
|     { | ||||
|       debug_printf ("at %d(%c) state is %d", *src, isprint (*src) ? *src : ' ', | ||||
| 		    dev_state.state_); | ||||
|       paranoid_printf ("char %0c state is %d", *src, dev_state.state_); | ||||
|       switch (dev_state.state_) | ||||
| 	{ | ||||
| 	case normal: | ||||
|   | ||||
| @@ -176,7 +176,7 @@ fhandler_pty_master::accept_input () | ||||
|       DWORD rc; | ||||
|       DWORD written = 0; | ||||
|  | ||||
|       termios_printf ("about to write %d chars to slave", bytes_left); | ||||
|       paranoid_printf ("about to write %d chars to slave", bytes_left); | ||||
|       rc = WriteFile (get_output_handle (), p, bytes_left, &written, NULL); | ||||
|       if (!rc) | ||||
| 	{ | ||||
|   | ||||
| @@ -517,19 +517,25 @@ sigfillset (sigset_t *set) | ||||
| extern "C" int | ||||
| sigsuspend (const sigset_t *set) | ||||
| { | ||||
|   return handle_sigsuspend (*set); | ||||
|   int res = handle_sigsuspend (*set); | ||||
|   syscall_printf ("%R = sigsuspend(%p)", res, set); | ||||
|   return res; | ||||
| } | ||||
|  | ||||
| extern "C" int | ||||
| sigpause (int signal_mask) | ||||
| { | ||||
|   return handle_sigsuspend ((sigset_t) signal_mask); | ||||
|   int res = handle_sigsuspend ((sigset_t) signal_mask); | ||||
|   syscall_printf ("%R = sigpause(%p)", res, signal_mask); | ||||
|   return res; | ||||
| } | ||||
|  | ||||
| extern "C" int | ||||
| pause (void) | ||||
| { | ||||
|   return handle_sigsuspend (_my_tls.sigmask); | ||||
|   int res = handle_sigsuspend (_my_tls.sigmask); | ||||
|   syscall_printf ("%R = pause()", res); | ||||
|   return res; | ||||
| } | ||||
|  | ||||
| extern "C" int | ||||
|   | ||||
| @@ -46,8 +46,7 @@ char NO_COPY myself_nowait_dummy[1] = {'0'};// Flag to sig_send that signal goes | ||||
|  | ||||
| #define Static static NO_COPY | ||||
|  | ||||
| HANDLE NO_COPY sigCONT;			// Used to "STOP" a process | ||||
|  | ||||
| Static HANDLE sig_hold;			// Used to stop signal processing | ||||
| Static bool sigheld;			// True if holding signals | ||||
|  | ||||
| Static int nprocs;			// Number of deceased children | ||||
| @@ -568,7 +567,7 @@ sig_send (_pinfo *p, int sig) | ||||
|     return 0; | ||||
|   else if (sig == __SIGNOHOLD || sig == __SIGEXIT) | ||||
|     { | ||||
|       SetEvent (sigCONT); | ||||
|       SetEvent (sig_hold); | ||||
|       sigheld = false; | ||||
|     } | ||||
|   else if (&_my_tls == _main_tls) | ||||
| @@ -1345,7 +1344,7 @@ static void WINAPI | ||||
| wait_sig (VOID *) | ||||
| { | ||||
|   _sig_tls = &_my_tls; | ||||
|   sigCONT = CreateEvent (&sec_none_nih, FALSE, FALSE, NULL); | ||||
|   sig_hold = CreateEvent (&sec_none_nih, FALSE, FALSE, NULL); | ||||
|  | ||||
|   sigproc_printf ("entering ReadFile loop, my_readsig %p, my_sendsig %p", | ||||
| 		  my_readsig, my_sendsig); | ||||
| @@ -1355,7 +1354,7 @@ wait_sig (VOID *) | ||||
|   for (;;) | ||||
|     { | ||||
|       if (pack.si.si_signo == __SIGHOLD) | ||||
| 	WaitForSingleObject (sigCONT, INFINITE); | ||||
| 	WaitForSingleObject (sig_hold, INFINITE); | ||||
|       DWORD nb; | ||||
|       pack.tls = NULL; | ||||
|       if (!ReadFile (my_readsig, &pack, sizeof (pack), &nb, NULL)) | ||||
|   | ||||
| @@ -58,8 +58,6 @@ struct sigpacket | ||||
|   int __stdcall process () __attribute__ ((regparm (1))); | ||||
| }; | ||||
|  | ||||
| extern HANDLE sigCONT; | ||||
|  | ||||
| void __stdcall sig_dispatch_pending (bool fast = false) | ||||
|   __attribute__ ((regparm (1))); | ||||
| void set_signal_mask (sigset_t&, sigset_t) __attribute__ ((regparm (2))); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user