Add '#include "cygwait.h"' throughout, where appropriate.
* DevNotes: Add entry cgf-000012. * Makefile.in (DLL_OFILES): Add cygwait.o. * sigproc.h: Remove cygwait definitions. * cygwait.h: New file. Define/declare Cygwin waitfor functions. * cygwait.cc: Ditto. * exceptions.cc: Include cygwait.h. (handle_sigsuspend): Accommodate change in cancelable_wait arguments. (sigpacket::process): Display thread tls in debugging output. * fhandler.cc (fhandler_base_overlapped::wait_overlapped): Use symbolic names for signal and cancel return. * fhandler_console.cc (fhandler_console::read): Ditto. (fhandler_dev_dsp::Audio_out::waitforspace): Ditto. fhandler_dev_dsp::Audio_in::waitfordata): Ditto. * fhandler_fifo.cc (fhandler_fifo::wait): Ditto. * fhandler_serial.cc (fhandler_serial::raw_read): Ditto. * fhandler_tty.cc (fhandler_pty_slave::read): Ditto. * select.cc (cygwin_select): Ditto. * wait.cc (wait4): Ditto. * thread.cc (cancelable_wait): Move definition to cygwait.h. (pthread_cond::wait): Accommodate change in cancelable_wait arguments. (pthread_mutex::lock): Ditto. (pthread_spinlock::lock): Ditto. (pthread::join): Ditto. (pthread::thread_init_wrapper): Display tls in debugging output. (semaphore::_timedwait): Ditto. * thread.h (cw_sig_wait): Move to cygwait.h. (cw_cancel_action): Delete. (cancelable_wait): Move declaration to cygwait.h.
This commit is contained in:
		@@ -1,3 +1,35 @@
 | 
			
		||||
2012-06-17  Christopher Faylor  <me.cygwin2012@cgf.cx>
 | 
			
		||||
 | 
			
		||||
	Add '#include "cygwait.h"' throughout, where appropriate.
 | 
			
		||||
	* DevNotes: Add entry cgf-000012.
 | 
			
		||||
	* Makefile.in (DLL_OFILES): Add cygwait.o.
 | 
			
		||||
	* sigproc.h: Remove cygwait definitions.
 | 
			
		||||
	* cygwait.h: New file.  Define/declare Cygwin waitfor functions.
 | 
			
		||||
	* cygwait.cc: Ditto.
 | 
			
		||||
	* exceptions.cc: Include cygwait.h.
 | 
			
		||||
	(handle_sigsuspend): Accommodate change in cancelable_wait arguments.
 | 
			
		||||
	(sigpacket::process): Display thread tls in debugging output.
 | 
			
		||||
	* fhandler.cc (fhandler_base_overlapped::wait_overlapped): Use symbolic
 | 
			
		||||
	names for signal and cancel return.
 | 
			
		||||
	* fhandler_console.cc (fhandler_console::read): Ditto.
 | 
			
		||||
	(fhandler_dev_dsp::Audio_out::waitforspace): Ditto.
 | 
			
		||||
	fhandler_dev_dsp::Audio_in::waitfordata): Ditto.
 | 
			
		||||
	* fhandler_fifo.cc (fhandler_fifo::wait): Ditto.
 | 
			
		||||
	* fhandler_serial.cc (fhandler_serial::raw_read): Ditto.
 | 
			
		||||
	* fhandler_tty.cc (fhandler_pty_slave::read): Ditto.
 | 
			
		||||
	* select.cc (cygwin_select): Ditto.
 | 
			
		||||
	* wait.cc (wait4): Ditto.
 | 
			
		||||
	* thread.cc (cancelable_wait): Move definition to cygwait.h.
 | 
			
		||||
	(pthread_cond::wait): Accommodate change in cancelable_wait arguments.
 | 
			
		||||
	(pthread_mutex::lock): Ditto.
 | 
			
		||||
	(pthread_spinlock::lock): Ditto.
 | 
			
		||||
	(pthread::join): Ditto.
 | 
			
		||||
	(pthread::thread_init_wrapper): Display tls in debugging output.
 | 
			
		||||
	(semaphore::_timedwait): Ditto.
 | 
			
		||||
	* thread.h (cw_sig_wait): Move to cygwait.h.
 | 
			
		||||
	(cw_cancel_action): Delete.
 | 
			
		||||
	(cancelable_wait): Move declaration to cygwait.h.
 | 
			
		||||
 | 
			
		||||
2012-06-11  Yaakov Selkowitz  <yselkowitz@users.sourceforge.net>
 | 
			
		||||
 | 
			
		||||
	* regex/regcomp.c (p_ere): Allow vertical-line following
 | 
			
		||||
 
 | 
			
		||||
@@ -1,3 +1,25 @@
 | 
			
		||||
2012-06-12  cgf-000012
 | 
			
		||||
 | 
			
		||||
These changes are the preliminary for redoing the way threads wait for
 | 
			
		||||
signals.  The problems are shown by the test case mentioned here:
 | 
			
		||||
 | 
			
		||||
http://cygwin.com/ml/cygwin/2012-05/msg00434.html
 | 
			
		||||
 | 
			
		||||
I've known that the signal handling in threads wasn't quite right for
 | 
			
		||||
some time.  I lost all of my thread signal tests in the great "rm -r"
 | 
			
		||||
debacle of a few years ago and have been less than enthusiastic about
 | 
			
		||||
redoing everything (I had PCTS tests and everyting).  But it really is
 | 
			
		||||
time to redo this signal handling to make it more like it is supposed to
 | 
			
		||||
be.
 | 
			
		||||
 | 
			
		||||
This change should not introduce any new behavior.  Things should
 | 
			
		||||
continue to behave as before.  The major differences are a change in the
 | 
			
		||||
arguments to cancelable_wait and cygwait now uses cancelable_wait and,
 | 
			
		||||
so, the returns from cygwait now mirror cancelable_wait.
 | 
			
		||||
 | 
			
		||||
The next change will consolidate cygwait and cancelable_wait into one
 | 
			
		||||
cygwait function.
 | 
			
		||||
 | 
			
		||||
2012-06-02  cgf-000011
 | 
			
		||||
 | 
			
		||||
The refcnt handling was tricky to get right but I had convinced myself
 | 
			
		||||
 
 | 
			
		||||
@@ -133,16 +133,16 @@ MALLOC_OFILES:=@MALLOC_OFILES@
 | 
			
		||||
DLL_IMPORTS:=$(w32api_lib)/libkernel32.a $(w32api_lib)/libntdll.a
 | 
			
		||||
 | 
			
		||||
MT_SAFE_OBJECTS:=
 | 
			
		||||
# Please maintain this list in sorted order, with maximum files per 86 col line
 | 
			
		||||
#
 | 
			
		||||
DLL_OFILES:=advapi32.o assert.o autoload.o bsdlib.o ctype.o cxx.o cygheap.o \
 | 
			
		||||
	cygthread.o cygtls.o cygxdr.o dcrt0.o debug.o devices.o dir.o dlfcn.o \
 | 
			
		||||
	dll_init.o dtable.o environ.o errno.o exceptions.o exec.o external.o \
 | 
			
		||||
	fcntl.o fenv.o fhandler.o fhandler_clipboard.o fhandler_console.o \
 | 
			
		||||
	fhandler_dev.o fhandler_disk_file.o fhandler_dsp.o fhandler_fifo.o \
 | 
			
		||||
	fhandler_floppy.o fhandler_mailslot.o fhandler_mem.o fhandler_netdrive.o \
 | 
			
		||||
	fhandler_nodevice.o fhandler_proc.o fhandler_process.o fhandler_procnet.o \
 | 
			
		||||
	fhandler_procsys.o fhandler_procsysvipc.o fhandler_random.o fhandler_raw.o \
 | 
			
		||||
	cygthread.o cygtls.o cygwait.o cygxdr.o dcrt0.o debug.o devices.o \
 | 
			
		||||
	dir.o dlfcn.o dll_init.o dtable.o environ.o errno.o exceptions.o \
 | 
			
		||||
	exec.o external.o fcntl.o fenv.o fhandler.o fhandler_clipboard.o \
 | 
			
		||||
	fhandler_console.o fhandler_dev.o fhandler_disk_file.o fhandler_dsp.o \
 | 
			
		||||
	fhandler_fifo.o fhandler_floppy.o fhandler_mailslot.o fhandler_mem.o \
 | 
			
		||||
	fhandler_netdrive.o fhandler_nodevice.o fhandler_proc.o \
 | 
			
		||||
	fhandler_process.o fhandler_procnet.o fhandler_procsys.o \
 | 
			
		||||
	fhandler_procsysvipc.o fhandler_random.o fhandler_raw.o \
 | 
			
		||||
	fhandler_registry.o fhandler_serial.o fhandler_socket.o fhandler_tape.o \
 | 
			
		||||
	fhandler_termios.o fhandler_tty.o fhandler_virtual.o fhandler_windows.o \
 | 
			
		||||
	fhandler_zero.o flock.o fnmatch.o fork.o fts.o ftw.o getopt.o glob.o \
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										108
									
								
								winsup/cygwin/cygwait.cc
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										108
									
								
								winsup/cygwin/cygwait.cc
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,108 @@
 | 
			
		||||
/* cygwait.h
 | 
			
		||||
 | 
			
		||||
   Copyright 2011, 2012 Red Hat, Inc.
 | 
			
		||||
 | 
			
		||||
   This file is part of Cygwin.
 | 
			
		||||
 | 
			
		||||
   This software is a copyrighted work licensed under the terms of the
 | 
			
		||||
   Cygwin license.  Please consult the file "CYGWIN_LICENSE" for
 | 
			
		||||
   details.  */
 | 
			
		||||
 | 
			
		||||
#include "winsup.h"
 | 
			
		||||
#include "sigproc.h"
 | 
			
		||||
#include "cygwait.h"
 | 
			
		||||
#include "ntdll.h"
 | 
			
		||||
 | 
			
		||||
#define is_cw_cancel		(mask & cw_cancel)
 | 
			
		||||
#define is_cw_cancel_self	(mask & cw_cancel_self)
 | 
			
		||||
#define is_cw_sig		(mask & cw_sig)
 | 
			
		||||
#define is_cw_sig_eintr		(mask & cw_sig_eintr)
 | 
			
		||||
#define is_cw_sig_return	(mask & cw_sig_return)
 | 
			
		||||
 | 
			
		||||
#define is_cw_sig_handle	(mask & (is_cw_sig | is_cw_sig_eintr))
 | 
			
		||||
 | 
			
		||||
DWORD
 | 
			
		||||
cancelable_wait (HANDLE object, PLARGE_INTEGER timeout, unsigned mask)
 | 
			
		||||
{
 | 
			
		||||
  DWORD res;
 | 
			
		||||
  DWORD num = 0;
 | 
			
		||||
  HANDLE wait_objects[4];
 | 
			
		||||
  pthread_t thread = pthread::self ();
 | 
			
		||||
 | 
			
		||||
  /* Do not change the wait order.
 | 
			
		||||
     The object must have higher priority than the cancel event,
 | 
			
		||||
     because WaitForMultipleObjects will return the smallest index
 | 
			
		||||
     if both objects are signaled. */
 | 
			
		||||
  if (object)
 | 
			
		||||
    wait_objects[num++] = object;
 | 
			
		||||
 | 
			
		||||
  DWORD sig_n;
 | 
			
		||||
  if (!is_cw_sig_handle)
 | 
			
		||||
    sig_n = WAIT_TIMEOUT + 1;
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      sig_n = WAIT_OBJECT_0 + num++;
 | 
			
		||||
      wait_objects[sig_n] = signal_arrived;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  DWORD cancel_n;
 | 
			
		||||
  if (!is_cw_cancel || !pthread::is_good_object (&thread) ||
 | 
			
		||||
      thread->cancelstate == PTHREAD_CANCEL_DISABLE)
 | 
			
		||||
    cancel_n = WAIT_TIMEOUT + 1;
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      cancel_n = WAIT_OBJECT_0 + num++;
 | 
			
		||||
      wait_objects[cancel_n] = thread->cancel_event;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  DWORD timeout_n;
 | 
			
		||||
  if (!timeout)
 | 
			
		||||
    timeout_n = WAIT_TIMEOUT + 1;
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      timeout_n = WAIT_OBJECT_0 + num++;
 | 
			
		||||
      if (!_my_tls.locals.cw_timer)
 | 
			
		||||
	NtCreateTimer (&_my_tls.locals.cw_timer, TIMER_ALL_ACCESS, NULL,
 | 
			
		||||
		       NotificationTimer);
 | 
			
		||||
      NtSetTimer (_my_tls.locals.cw_timer, timeout, NULL, NULL, FALSE, 0, NULL);
 | 
			
		||||
      wait_objects[timeout_n] = _my_tls.locals.cw_timer;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  while (1)
 | 
			
		||||
    {
 | 
			
		||||
      res = WaitForMultipleObjects (num, wait_objects, FALSE, INFINITE);
 | 
			
		||||
      if (res == cancel_n)
 | 
			
		||||
	{
 | 
			
		||||
	  if (is_cw_cancel_self)
 | 
			
		||||
	    pthread::static_cancel_self ();
 | 
			
		||||
	  res = WAIT_CANCELED;
 | 
			
		||||
	}
 | 
			
		||||
      else if (res == timeout_n)
 | 
			
		||||
	res = WAIT_TIMEOUT;
 | 
			
		||||
      else if (res != sig_n)
 | 
			
		||||
	/* all set */;
 | 
			
		||||
      else if (is_cw_sig_eintr)
 | 
			
		||||
	res = WAIT_SIGNALED;
 | 
			
		||||
      else
 | 
			
		||||
	{
 | 
			
		||||
	  _my_tls.call_signal_handler ();
 | 
			
		||||
	  continue;
 | 
			
		||||
	}
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (timeout)
 | 
			
		||||
    {
 | 
			
		||||
      TIMER_BASIC_INFORMATION tbi;
 | 
			
		||||
 | 
			
		||||
      NtQueryTimer (_my_tls.locals.cw_timer, TimerBasicInformation, &tbi,
 | 
			
		||||
		    sizeof tbi, NULL);
 | 
			
		||||
      /* if timer expired, TimeRemaining is negative and represents the
 | 
			
		||||
	  system uptime when signalled */
 | 
			
		||||
      if (timeout->QuadPart < 0LL)
 | 
			
		||||
	timeout->QuadPart = tbi.SignalState ? 0LL : tbi.TimeRemaining.QuadPart;
 | 
			
		||||
      NtCancelTimer (_my_tls.locals.cw_timer, NULL);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return res;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										47
									
								
								winsup/cygwin/cygwait.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										47
									
								
								winsup/cygwin/cygwait.h
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,47 @@
 | 
			
		||||
/* cygwait.h
 | 
			
		||||
 | 
			
		||||
   Copyright 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
 | 
			
		||||
   Red Hat, Inc.
 | 
			
		||||
 | 
			
		||||
   This file is part of Cygwin.
 | 
			
		||||
 | 
			
		||||
   This software is a copyrighted work licensed under the terms of the
 | 
			
		||||
   Cygwin license.  Please consult the file "CYGWIN_LICENSE" for
 | 
			
		||||
   details.  */
 | 
			
		||||
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
enum cw_wait_mask
 | 
			
		||||
{
 | 
			
		||||
  cw_cancel =		0x0001,
 | 
			
		||||
  cw_cancel_self =	0x0002,
 | 
			
		||||
  cw_sig =		0x0004,
 | 
			
		||||
  cw_sig_eintr =	0x0008
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const unsigned cw_std_mask = cw_cancel | cw_cancel_self | cw_sig;
 | 
			
		||||
 | 
			
		||||
DWORD cancelable_wait (HANDLE, PLARGE_INTEGER timeout = NULL,
 | 
			
		||||
		       unsigned = cw_std_mask)
 | 
			
		||||
  __attribute__ ((regparm (3)));
 | 
			
		||||
 | 
			
		||||
static inline DWORD __attribute__ ((always_inline))
 | 
			
		||||
cygwait (HANDLE h, DWORD howlong = INFINITE)
 | 
			
		||||
{
 | 
			
		||||
  PLARGE_INTEGER pli_howlong;
 | 
			
		||||
  LARGE_INTEGER li_howlong;
 | 
			
		||||
  if (howlong == INFINITE)
 | 
			
		||||
    pli_howlong = NULL;
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      li_howlong.QuadPart = 10000ULL * howlong;
 | 
			
		||||
      pli_howlong = &li_howlong;
 | 
			
		||||
    }
 | 
			
		||||
  return cancelable_wait (h, pli_howlong, cw_cancel | cw_sig_eintr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline DWORD __attribute__ ((always_inline))
 | 
			
		||||
cygwait (DWORD howlong)
 | 
			
		||||
{
 | 
			
		||||
  return cygwait ((HANDLE) NULL, howlong);
 | 
			
		||||
}
 | 
			
		||||
@@ -31,6 +31,7 @@ details. */
 | 
			
		||||
#include "child_info.h"
 | 
			
		||||
#include "ntdll.h"
 | 
			
		||||
#include "exception.h"
 | 
			
		||||
#include "cygwait.h"
 | 
			
		||||
 | 
			
		||||
#define CALL_HANDLER_RETRY_OUTER 10
 | 
			
		||||
#define CALL_HANDLER_RETRY_INNER 10
 | 
			
		||||
@@ -714,7 +715,7 @@ handle_sigsuspend (sigset_t tempmask)
 | 
			
		||||
  sigproc_printf ("oldmask %p, newmask %p", oldmask, tempmask);
 | 
			
		||||
 | 
			
		||||
  pthread_testcancel ();
 | 
			
		||||
  cancelable_wait (signal_arrived);
 | 
			
		||||
  cancelable_wait (signal_arrived, NULL, cw_cancel | cw_cancel_self);
 | 
			
		||||
 | 
			
		||||
  set_sig_errno (EINTR);	// Per POSIX
 | 
			
		||||
 | 
			
		||||
@@ -1194,6 +1195,7 @@ sigpacket::process ()
 | 
			
		||||
    handler = NULL;
 | 
			
		||||
 | 
			
		||||
  _cygtls *use_tls = tls ?: _main_tls;
 | 
			
		||||
  sigproc_printf ("tls %p, use_tls %p", tls, use_tls);
 | 
			
		||||
 | 
			
		||||
  if (si.si_signo == SIGKILL)
 | 
			
		||||
    goto exit_sig;
 | 
			
		||||
 
 | 
			
		||||
@@ -31,6 +31,7 @@ details. */
 | 
			
		||||
#include "sigproc.h"
 | 
			
		||||
#include "shared_info.h"
 | 
			
		||||
#include <asm/socket.h>
 | 
			
		||||
#include "cygwait.h"
 | 
			
		||||
 | 
			
		||||
#define MAX_OVERLAPPED_WRITE_LEN (64 * 1024 * 1024)
 | 
			
		||||
#define MIN_OVERLAPPED_WRITE_LEN (1 * 1024 * 1024)
 | 
			
		||||
@@ -1939,7 +1940,7 @@ fhandler_base_overlapped::wait_overlapped (bool inres, bool writing, DWORD *byte
 | 
			
		||||
	    case WAIT_OBJECT_0:
 | 
			
		||||
	      err = ERROR_INVALID_HANDLE;
 | 
			
		||||
	      break;
 | 
			
		||||
	    case WAIT_OBJECT_0 + 1:
 | 
			
		||||
	    case WAIT_SIGNALED:
 | 
			
		||||
	      err = ERROR_INVALID_AT_INTERRUPT_TIME;
 | 
			
		||||
	      break;
 | 
			
		||||
	    default:
 | 
			
		||||
 
 | 
			
		||||
@@ -36,6 +36,7 @@ details. */
 | 
			
		||||
#include <asm/socket.h>
 | 
			
		||||
#include "sync.h"
 | 
			
		||||
#include "child_info.h"
 | 
			
		||||
#include "cygwait.h"
 | 
			
		||||
 | 
			
		||||
/* Don't make this bigger than NT_MAX_PATH as long as the temporary buffer
 | 
			
		||||
   is allocated using tmp_pathbuf!!! */
 | 
			
		||||
@@ -355,9 +356,9 @@ fhandler_console::read (void *pv, size_t& buflen)
 | 
			
		||||
	{
 | 
			
		||||
	case WAIT_OBJECT_0:
 | 
			
		||||
	  break;
 | 
			
		||||
	case WAIT_OBJECT_0 + 1:
 | 
			
		||||
	case WAIT_SIGNALED:
 | 
			
		||||
	  goto sig_exit;
 | 
			
		||||
	case WAIT_OBJECT_0 + 2:
 | 
			
		||||
	case WAIT_CANCELED:
 | 
			
		||||
	  process_state.pop ();
 | 
			
		||||
	  pthread::static_cancel_self ();
 | 
			
		||||
	  /*NOTREACHED*/
 | 
			
		||||
 
 | 
			
		||||
@@ -21,6 +21,7 @@ details. */
 | 
			
		||||
#include "dtable.h"
 | 
			
		||||
#include "cygheap.h"
 | 
			
		||||
#include "sigproc.h"
 | 
			
		||||
#include "cygwait.h"
 | 
			
		||||
 | 
			
		||||
/*------------------------------------------------------------------------
 | 
			
		||||
  Simple encapsulation of the win32 audio device.
 | 
			
		||||
@@ -544,14 +545,14 @@ fhandler_dev_dsp::Audio_out::waitforspace ()
 | 
			
		||||
      debug_printf ("100ms");
 | 
			
		||||
      switch (cygwait (100))
 | 
			
		||||
	{
 | 
			
		||||
	case WAIT_OBJECT_0:
 | 
			
		||||
	case WAIT_SIGNALED:
 | 
			
		||||
	  if (!_my_tls.call_signal_handler ())
 | 
			
		||||
	    {
 | 
			
		||||
	      set_errno (EINTR);
 | 
			
		||||
	      return false;
 | 
			
		||||
	    }
 | 
			
		||||
	  break;
 | 
			
		||||
	case WAIT_OBJECT_0 + 1:
 | 
			
		||||
	case WAIT_CANCELED:
 | 
			
		||||
	  pthread::static_cancel_self ();
 | 
			
		||||
	  /*NOTREACHED*/
 | 
			
		||||
	default:
 | 
			
		||||
@@ -922,14 +923,14 @@ fhandler_dev_dsp::Audio_in::waitfordata ()
 | 
			
		||||
      debug_printf ("100ms");
 | 
			
		||||
      switch (cygwait (100))
 | 
			
		||||
	{
 | 
			
		||||
	case WAIT_OBJECT_0:
 | 
			
		||||
	case WAIT_SIGNALED:
 | 
			
		||||
	  if (!_my_tls.call_signal_handler ())
 | 
			
		||||
	    {
 | 
			
		||||
	      set_errno (EINTR);
 | 
			
		||||
	      return false;
 | 
			
		||||
	    }
 | 
			
		||||
	  break;
 | 
			
		||||
	case WAIT_OBJECT_0 + 1:
 | 
			
		||||
	case WAIT_CANCELED:
 | 
			
		||||
	  pthread::static_cancel_self ();
 | 
			
		||||
	  /*NOTREACHED*/
 | 
			
		||||
	default:
 | 
			
		||||
 
 | 
			
		||||
@@ -22,6 +22,7 @@
 | 
			
		||||
#include "cygtls.h"
 | 
			
		||||
#include "shared_info.h"
 | 
			
		||||
#include "ntdll.h"
 | 
			
		||||
#include "cygwait.h"
 | 
			
		||||
 | 
			
		||||
fhandler_fifo::fhandler_fifo ():
 | 
			
		||||
  fhandler_base_overlapped (),
 | 
			
		||||
@@ -242,6 +243,14 @@ fhandler_fifo::wait (HANDLE h)
 | 
			
		||||
    case WAIT_OBJECT_0:
 | 
			
		||||
      debug_only_printf ("successfully waited for %s", what);
 | 
			
		||||
      return true;
 | 
			
		||||
    case WAIT_SIGNALED:
 | 
			
		||||
      debug_only_printf ("interrupted by signal while waiting for %s", what);
 | 
			
		||||
      set_errno (EINTR);
 | 
			
		||||
      return false;
 | 
			
		||||
    case WAIT_CANCELED:
 | 
			
		||||
      debug_only_printf ("cancellable interruption while waiting for %s", what);
 | 
			
		||||
      pthread::static_cancel_self ();	/* never returns */
 | 
			
		||||
      break;
 | 
			
		||||
    case WAIT_TIMEOUT:
 | 
			
		||||
      if (h == write_ready)
 | 
			
		||||
	{
 | 
			
		||||
@@ -254,14 +263,6 @@ fhandler_fifo::wait (HANDLE h)
 | 
			
		||||
	  return false;
 | 
			
		||||
	}
 | 
			
		||||
      break;
 | 
			
		||||
    case WAIT_OBJECT_0 + 1:
 | 
			
		||||
      debug_only_printf ("interrupted by signal while waiting for %s", what);
 | 
			
		||||
      set_errno (EINTR);
 | 
			
		||||
      return false;
 | 
			
		||||
    case WAIT_OBJECT_0 + 2:
 | 
			
		||||
      debug_only_printf ("cancellable interruption while waiting for %s", what);
 | 
			
		||||
      pthread::static_cancel_self ();	/* never returns */
 | 
			
		||||
      break;
 | 
			
		||||
    default:
 | 
			
		||||
      debug_only_printf ("unknown error while waiting for %s", what);
 | 
			
		||||
      __seterrno ();
 | 
			
		||||
 
 | 
			
		||||
@@ -20,6 +20,7 @@ details. */
 | 
			
		||||
#include "pinfo.h"
 | 
			
		||||
#include <asm/socket.h>
 | 
			
		||||
#include <ddk/ntddser.h>
 | 
			
		||||
#include "cygwait.h"
 | 
			
		||||
 | 
			
		||||
/**********************************************************************/
 | 
			
		||||
/* fhandler_serial */
 | 
			
		||||
@@ -94,13 +95,13 @@ fhandler_serial::raw_read (void *ptr, size_t& ulen)
 | 
			
		||||
		    goto err;
 | 
			
		||||
		  debug_printf ("n %d, ev %x", n, ev);
 | 
			
		||||
		  break;
 | 
			
		||||
		case WAIT_OBJECT_0 + 1:
 | 
			
		||||
		case WAIT_SIGNALED:
 | 
			
		||||
		  tot = -1;
 | 
			
		||||
		  PurgeComm (get_handle (), PURGE_RXABORT);
 | 
			
		||||
		  overlapped_armed = 0;
 | 
			
		||||
		  set_sig_errno (EINTR);
 | 
			
		||||
		  goto out;
 | 
			
		||||
		case WAIT_OBJECT_0 + 2:
 | 
			
		||||
		case WAIT_CANCELED:
 | 
			
		||||
		  PurgeComm (get_handle (), PURGE_RXABORT);
 | 
			
		||||
		  overlapped_armed = 0;
 | 
			
		||||
		  pthread::static_cancel_self ();
 | 
			
		||||
@@ -201,12 +202,12 @@ fhandler_serial::raw_write (const void *ptr, size_t len)
 | 
			
		||||
	    {
 | 
			
		||||
	    case WAIT_OBJECT_0:
 | 
			
		||||
	      break;
 | 
			
		||||
	    case WAIT_OBJECT_0 + 1:
 | 
			
		||||
	    case WAIT_SIGNALED:
 | 
			
		||||
	      PurgeComm (get_handle (), PURGE_TXABORT);
 | 
			
		||||
	      set_sig_errno (EINTR);
 | 
			
		||||
	      ForceCloseHandle (write_status.hEvent);
 | 
			
		||||
	      return -1;
 | 
			
		||||
	    case WAIT_OBJECT_0 + 2:
 | 
			
		||||
	    case WAIT_CANCELED:
 | 
			
		||||
	      PurgeComm (get_handle (), PURGE_TXABORT);
 | 
			
		||||
	      pthread::static_cancel_self ();
 | 
			
		||||
	      /*NOTREACHED*/
 | 
			
		||||
 
 | 
			
		||||
@@ -26,6 +26,7 @@ details. */
 | 
			
		||||
#include "cygthread.h"
 | 
			
		||||
#include "child_info.h"
 | 
			
		||||
#include <asm/socket.h>
 | 
			
		||||
#include "cygwait.h"
 | 
			
		||||
 | 
			
		||||
#define close_maybe(h) \
 | 
			
		||||
  do { \
 | 
			
		||||
@@ -737,14 +738,14 @@ fhandler_pty_slave::read (void *ptr, size_t& len)
 | 
			
		||||
	      goto out;
 | 
			
		||||
	    }
 | 
			
		||||
	  break;
 | 
			
		||||
	case WAIT_OBJECT_0 + 1:
 | 
			
		||||
	case WAIT_SIGNALED:
 | 
			
		||||
	  if (totalread > 0)
 | 
			
		||||
	    goto out;
 | 
			
		||||
	  termios_printf ("wait catched signal");
 | 
			
		||||
	  set_sig_errno (EINTR);
 | 
			
		||||
	  totalread = -1;
 | 
			
		||||
	  goto out;
 | 
			
		||||
	case WAIT_OBJECT_0 + 2:
 | 
			
		||||
	case WAIT_CANCELED:
 | 
			
		||||
	  process_state.pop ();
 | 
			
		||||
	  pthread::static_cancel_self ();
 | 
			
		||||
	  /*NOTREACHED*/
 | 
			
		||||
@@ -772,14 +773,14 @@ fhandler_pty_slave::read (void *ptr, size_t& len)
 | 
			
		||||
	case WAIT_OBJECT_0:
 | 
			
		||||
	case WAIT_ABANDONED_0:
 | 
			
		||||
	  break;
 | 
			
		||||
	case WAIT_OBJECT_0 + 1:
 | 
			
		||||
	case WAIT_SIGNALED:
 | 
			
		||||
	  if (totalread > 0)
 | 
			
		||||
	    goto out;
 | 
			
		||||
	  termios_printf ("wait for mutex catched signal");
 | 
			
		||||
	  termios_printf ("wait for mutex caught signal");
 | 
			
		||||
	  set_sig_errno (EINTR);
 | 
			
		||||
	  totalread = -1;
 | 
			
		||||
	  goto out;
 | 
			
		||||
	case WAIT_OBJECT_0 + 2:
 | 
			
		||||
	case WAIT_CANCELED:
 | 
			
		||||
	  process_state.pop ();
 | 
			
		||||
	  pthread::static_cancel_self ();
 | 
			
		||||
	  /*NOTREACHED*/
 | 
			
		||||
 
 | 
			
		||||
@@ -34,6 +34,7 @@ details. */
 | 
			
		||||
#include "pinfo.h"
 | 
			
		||||
#include "sigproc.h"
 | 
			
		||||
#include "cygtls.h"
 | 
			
		||||
#include "cygwait.h"
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * All these defines below should be in sys/types.h
 | 
			
		||||
@@ -143,7 +144,7 @@ cygwin_select (int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
 | 
			
		||||
      if (sel.start.next == NULL)
 | 
			
		||||
	switch (cygwait (ms))
 | 
			
		||||
	  {
 | 
			
		||||
	  case WAIT_OBJECT_0:
 | 
			
		||||
	  case WAIT_SIGNALED:
 | 
			
		||||
	    select_printf ("signal received");
 | 
			
		||||
	    _my_tls.call_signal_handler ();
 | 
			
		||||
	    if (!sel.return_on_signal)
 | 
			
		||||
@@ -154,7 +155,7 @@ cygwin_select (int maxfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
 | 
			
		||||
		res = select_stuff::select_error;
 | 
			
		||||
	      }
 | 
			
		||||
	    break;
 | 
			
		||||
	  case WAIT_OBJECT_0 + 1:
 | 
			
		||||
	  case WAIT_CANCELED:
 | 
			
		||||
	    sel.destroy ();
 | 
			
		||||
	    pthread::static_cancel_self ();
 | 
			
		||||
	    /*NOTREACHED*/
 | 
			
		||||
 
 | 
			
		||||
@@ -22,6 +22,7 @@ details. */
 | 
			
		||||
#include "fhandler.h"
 | 
			
		||||
#include "dtable.h"
 | 
			
		||||
#include "cygheap.h"
 | 
			
		||||
#include "cygwait.h"
 | 
			
		||||
 | 
			
		||||
#define _SA_NORESTART	0x8000
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -80,33 +80,6 @@ void __stdcall proc_terminate ();
 | 
			
		||||
void __stdcall sigproc_init ();
 | 
			
		||||
#ifdef __INSIDE_CYGWIN__
 | 
			
		||||
void __stdcall sigproc_terminate (enum exit_states);
 | 
			
		||||
 | 
			
		||||
static inline DWORD __attribute__ ((always_inline))
 | 
			
		||||
cygwait (HANDLE h, DWORD howlong = INFINITE)
 | 
			
		||||
{
 | 
			
		||||
  HANDLE w4[3];
 | 
			
		||||
  DWORD n = 0;
 | 
			
		||||
  DWORD wait_signal;
 | 
			
		||||
  if ((w4[n] = h) != NULL)
 | 
			
		||||
    wait_signal = WAIT_OBJECT_0 + ++n;
 | 
			
		||||
  else
 | 
			
		||||
    wait_signal = WAIT_OBJECT_0 + 15;	/* Arbitrary.  Don't call signal
 | 
			
		||||
					   handler if only waiting for signal */
 | 
			
		||||
  w4[n++] = signal_arrived;
 | 
			
		||||
  if ((w4[n] = pthread::get_cancel_event ()) != NULL)
 | 
			
		||||
    n++;
 | 
			
		||||
  DWORD res;
 | 
			
		||||
  while ((res = WaitForMultipleObjects (n, w4, FALSE, howlong)) == wait_signal
 | 
			
		||||
	 && (_my_tls.call_signal_handler () || &_my_tls != _main_tls))
 | 
			
		||||
    continue;
 | 
			
		||||
  return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static inline DWORD __attribute__ ((always_inline))
 | 
			
		||||
cygwait (DWORD wait)
 | 
			
		||||
{
 | 
			
		||||
  return cygwait ((HANDLE) NULL, wait);
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
bool __stdcall pid_exists (pid_t) __attribute__ ((regparm(1)));
 | 
			
		||||
int __stdcall sig_send (_pinfo *, siginfo_t&, class _cygtls *tls = NULL) __attribute__ ((regparm (3)));
 | 
			
		||||
 
 | 
			
		||||
@@ -32,6 +32,7 @@ details. */
 | 
			
		||||
#include "dtable.h"
 | 
			
		||||
#include "cygheap.h"
 | 
			
		||||
#include "ntdll.h"
 | 
			
		||||
#include "cygwait.h"
 | 
			
		||||
 | 
			
		||||
extern "C" void __fp_lock_all ();
 | 
			
		||||
extern "C" void __fp_unlock_all ();
 | 
			
		||||
@@ -937,92 +938,6 @@ pthread::static_cancel_self ()
 | 
			
		||||
  pthread::self ()->cancel_self ();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
DWORD
 | 
			
		||||
cancelable_wait (HANDLE object, PLARGE_INTEGER timeout,
 | 
			
		||||
		 const cw_cancel_action cancel_action,
 | 
			
		||||
		 const enum cw_sig_wait sig_wait)
 | 
			
		||||
{
 | 
			
		||||
  DWORD res;
 | 
			
		||||
  DWORD num = 0;
 | 
			
		||||
  HANDLE wait_objects[4];
 | 
			
		||||
  pthread_t thread = pthread::self ();
 | 
			
		||||
 | 
			
		||||
  /* Do not change the wait order.
 | 
			
		||||
     The object must have higher priority than the cancel event,
 | 
			
		||||
     because WaitForMultipleObjects will return the smallest index
 | 
			
		||||
     if both objects are signaled. */
 | 
			
		||||
  wait_objects[num++] = object;
 | 
			
		||||
  DWORD cancel_n;
 | 
			
		||||
  if (cancel_action == cw_no_cancel || !pthread::is_good_object (&thread) ||
 | 
			
		||||
      thread->cancelstate == PTHREAD_CANCEL_DISABLE)
 | 
			
		||||
    cancel_n = WAIT_TIMEOUT + 1;
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      cancel_n = WAIT_OBJECT_0 + num++;
 | 
			
		||||
      wait_objects[cancel_n] = thread->cancel_event;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  DWORD sig_n;
 | 
			
		||||
  if (sig_wait == cw_sig_nosig)
 | 
			
		||||
    sig_n = WAIT_TIMEOUT + 1;
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      sig_n = WAIT_OBJECT_0 + num++;
 | 
			
		||||
      wait_objects[sig_n] = signal_arrived;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  DWORD timeout_n;
 | 
			
		||||
  if (!timeout)
 | 
			
		||||
    timeout_n = WAIT_TIMEOUT + 1;
 | 
			
		||||
  else
 | 
			
		||||
    {
 | 
			
		||||
      timeout_n = WAIT_OBJECT_0 + num++;
 | 
			
		||||
      if (!_my_tls.locals.cw_timer)
 | 
			
		||||
	NtCreateTimer (&_my_tls.locals.cw_timer, TIMER_ALL_ACCESS, NULL,
 | 
			
		||||
		       NotificationTimer);
 | 
			
		||||
      NtSetTimer (_my_tls.locals.cw_timer, timeout, NULL, NULL, FALSE, 0, NULL);
 | 
			
		||||
      wait_objects[timeout_n] = _my_tls.locals.cw_timer;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  while (1)
 | 
			
		||||
    {
 | 
			
		||||
      res = WaitForMultipleObjects (num, wait_objects, FALSE, INFINITE);
 | 
			
		||||
      if (res == cancel_n)
 | 
			
		||||
	{
 | 
			
		||||
	  if (cancel_action == cw_cancel_self)
 | 
			
		||||
	    pthread::static_cancel_self ();
 | 
			
		||||
	  res = WAIT_CANCELED;
 | 
			
		||||
	}
 | 
			
		||||
      else if (res == timeout_n)
 | 
			
		||||
	res = WAIT_TIMEOUT;
 | 
			
		||||
      else if (res != sig_n)
 | 
			
		||||
	/* all set */;
 | 
			
		||||
      else if (sig_wait == cw_sig_eintr)
 | 
			
		||||
	res = WAIT_SIGNALED;
 | 
			
		||||
      else
 | 
			
		||||
	{
 | 
			
		||||
	  _my_tls.call_signal_handler ();
 | 
			
		||||
	  continue;
 | 
			
		||||
	}
 | 
			
		||||
      break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  if (timeout)
 | 
			
		||||
    {
 | 
			
		||||
      TIMER_BASIC_INFORMATION tbi;
 | 
			
		||||
 | 
			
		||||
      NtQueryTimer (_my_tls.locals.cw_timer, TimerBasicInformation, &tbi,
 | 
			
		||||
		    sizeof tbi, NULL);
 | 
			
		||||
      /* if timer expired, TimeRemaining is negative and represents the
 | 
			
		||||
	  system uptime when signalled */
 | 
			
		||||
      if (timeout->QuadPart < 0LL)
 | 
			
		||||
	timeout->QuadPart = tbi.SignalState ? 0LL : tbi.TimeRemaining.QuadPart;
 | 
			
		||||
      NtCancelTimer (_my_tls.locals.cw_timer, NULL);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  return res;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int
 | 
			
		||||
pthread::setcancelstate (int state, int *oldstate)
 | 
			
		||||
{
 | 
			
		||||
@@ -1313,7 +1228,7 @@ pthread_cond::wait (pthread_mutex_t mutex, PLARGE_INTEGER timeout)
 | 
			
		||||
  ++mutex->condwaits;
 | 
			
		||||
  mutex->unlock ();
 | 
			
		||||
 | 
			
		||||
  rv = cancelable_wait (sem_wait, timeout, cw_no_cancel_self, cw_sig_eintr);
 | 
			
		||||
  rv = cancelable_wait (sem_wait, timeout, cw_cancel | cw_sig_eintr);
 | 
			
		||||
 | 
			
		||||
  mtx_out.lock ();
 | 
			
		||||
 | 
			
		||||
@@ -1828,7 +1743,8 @@ pthread_mutex::lock ()
 | 
			
		||||
  else if (type == PTHREAD_MUTEX_NORMAL /* potentially causes deadlock */
 | 
			
		||||
	   || !pthread::equal (owner, self))
 | 
			
		||||
    {
 | 
			
		||||
      cancelable_wait (win32_obj_id, NULL, cw_no_cancel, cw_sig_resume);
 | 
			
		||||
      /* FIXME: no cancel? */
 | 
			
		||||
      cancelable_wait (win32_obj_id, NULL, cw_sig);
 | 
			
		||||
      set_owner (self);
 | 
			
		||||
    }
 | 
			
		||||
  else
 | 
			
		||||
@@ -1968,7 +1884,8 @@ pthread_spinlock::lock ()
 | 
			
		||||
	  /* Minimal timeout to minimize CPU usage while still spinning. */
 | 
			
		||||
	  LARGE_INTEGER timeout;
 | 
			
		||||
	  timeout.QuadPart = -10000LL;
 | 
			
		||||
	  cancelable_wait (win32_obj_id, &timeout, cw_no_cancel, cw_sig_resume);
 | 
			
		||||
	  /* FIXME: no cancel? */
 | 
			
		||||
	  cancelable_wait (win32_obj_id, &timeout, cw_sig);
 | 
			
		||||
	}
 | 
			
		||||
    }
 | 
			
		||||
  while (result == -1);
 | 
			
		||||
@@ -2013,6 +1930,7 @@ pthread::thread_init_wrapper (void *arg)
 | 
			
		||||
  _my_tls.sigmask = thread->parent_sigmask;
 | 
			
		||||
  thread->mutex.unlock ();
 | 
			
		||||
 | 
			
		||||
  debug_printf ("tid %p", &_my_tls);
 | 
			
		||||
  thread_printf ("started thread %p %p %p %p %p %p", arg, &_my_tls.local_clib,
 | 
			
		||||
		 _impure_ptr, thread, thread->function, thread->arg);
 | 
			
		||||
 | 
			
		||||
@@ -2446,7 +2364,7 @@ pthread::join (pthread_t *thread, void **return_val)
 | 
			
		||||
      (*thread)->attr.joinable = PTHREAD_CREATE_DETACHED;
 | 
			
		||||
      (*thread)->mutex.unlock ();
 | 
			
		||||
 | 
			
		||||
      switch (cancelable_wait ((*thread)->win32_obj_id, NULL, cw_no_cancel_self, cw_sig_resume))
 | 
			
		||||
      switch (cancelable_wait ((*thread)->win32_obj_id, NULL, cw_sig | cw_cancel))
 | 
			
		||||
	{
 | 
			
		||||
	case WAIT_OBJECT_0:
 | 
			
		||||
	  if (return_val)
 | 
			
		||||
@@ -3561,7 +3479,7 @@ semaphore::_timedwait (const struct timespec *abstime)
 | 
			
		||||
  timeout.QuadPart = abstime->tv_sec * NSPERSEC
 | 
			
		||||
		     + (abstime->tv_nsec + 99) / 100 + FACTOR;
 | 
			
		||||
 | 
			
		||||
  switch (cancelable_wait (win32_obj_id, &timeout, cw_cancel_self, cw_sig_eintr))
 | 
			
		||||
  switch (cancelable_wait (win32_obj_id, &timeout, cw_cancel | cw_cancel_self | cw_sig_eintr))
 | 
			
		||||
    {
 | 
			
		||||
    case WAIT_OBJECT_0:
 | 
			
		||||
      currentvalue--;
 | 
			
		||||
@@ -3583,7 +3501,7 @@ semaphore::_timedwait (const struct timespec *abstime)
 | 
			
		||||
int
 | 
			
		||||
semaphore::_wait ()
 | 
			
		||||
{
 | 
			
		||||
  switch (cancelable_wait (win32_obj_id, NULL, cw_cancel_self, cw_sig_eintr))
 | 
			
		||||
  switch (cancelable_wait (win32_obj_id, NULL, cw_cancel | cw_cancel_self | cw_sig_eintr))
 | 
			
		||||
    {
 | 
			
		||||
    case WAIT_OBJECT_0:
 | 
			
		||||
      currentvalue--;
 | 
			
		||||
 
 | 
			
		||||
@@ -29,25 +29,7 @@ details. */
 | 
			
		||||
#include "security.h"
 | 
			
		||||
#include <errno.h>
 | 
			
		||||
#include "cygerrno.h"
 | 
			
		||||
 | 
			
		||||
enum cw_sig_wait
 | 
			
		||||
{
 | 
			
		||||
  cw_sig_nosig,
 | 
			
		||||
  cw_sig_eintr,
 | 
			
		||||
  cw_sig_resume
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum cw_cancel_action
 | 
			
		||||
{
 | 
			
		||||
  cw_cancel_self,
 | 
			
		||||
  cw_no_cancel_self,
 | 
			
		||||
  cw_no_cancel
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
DWORD cancelable_wait (HANDLE, PLARGE_INTEGER timeout = NULL,
 | 
			
		||||
		       const cw_cancel_action = cw_cancel_self,
 | 
			
		||||
		       const enum cw_sig_wait = cw_sig_nosig)
 | 
			
		||||
  __attribute__ ((regparm (3)));
 | 
			
		||||
#include "cygwait.h"
 | 
			
		||||
 | 
			
		||||
class fast_mutex
 | 
			
		||||
{
 | 
			
		||||
@@ -78,7 +60,7 @@ public:
 | 
			
		||||
  void lock ()
 | 
			
		||||
  {
 | 
			
		||||
    if (InterlockedIncrement ((long *) &lock_counter) != 1)
 | 
			
		||||
      cancelable_wait (win32_obj_id, NULL, cw_no_cancel, cw_sig_resume);
 | 
			
		||||
      cancelable_wait (win32_obj_id, NULL, cw_sig);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  void unlock ()
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
/* wait.cc: Posix wait routines.
 | 
			
		||||
 | 
			
		||||
   Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
 | 
			
		||||
   2005, 2009, 2011 Red Hat, Inc.
 | 
			
		||||
   2005, 2009, 2011, 2012 Red Hat, Inc.
 | 
			
		||||
 | 
			
		||||
This file is part of Cygwin.
 | 
			
		||||
 | 
			
		||||
@@ -14,6 +14,7 @@ details. */
 | 
			
		||||
#include "sigproc.h"
 | 
			
		||||
#include "thread.h"
 | 
			
		||||
#include "cygtls.h"
 | 
			
		||||
#include "cygwait.h"
 | 
			
		||||
 | 
			
		||||
/* This is called _wait and not wait because the real wait is defined
 | 
			
		||||
   in libc/syscalls/syswait.c.  It calls us.  */
 | 
			
		||||
@@ -79,7 +80,7 @@ wait4 (int intpid, int *status, int options, struct rusage *r)
 | 
			
		||||
      if ((waitfor = w->ev) == NULL)
 | 
			
		||||
	goto nochildren;
 | 
			
		||||
 | 
			
		||||
      res = cancelable_wait (waitfor);
 | 
			
		||||
      res = cancelable_wait (waitfor, NULL, cw_cancel | cw_cancel_self);
 | 
			
		||||
 | 
			
		||||
      sigproc_printf ("%d = cancelable_wait (...)", res);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user