* 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:
		
							parent
							
								
									c1a11ccfca
								
							
						
					
					
						commit
						d239805457
					
				| 
						 | 
				
			
			@ -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)));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue