]> sourceware.org Git - newlib-cygwin.git/commitdiff
Add '#include "cygwait.h"' throughout, where appropriate.
authorChristopher Faylor <me@cgf.cx>
Sun, 17 Jun 2012 20:50:24 +0000 (20:50 +0000)
committerChristopher Faylor <me@cgf.cx>
Sun, 17 Jun 2012 20:50:24 +0000 (20:50 +0000)
* 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.

18 files changed:
winsup/cygwin/ChangeLog
winsup/cygwin/DevNotes
winsup/cygwin/Makefile.in
winsup/cygwin/cygwait.cc [new file with mode: 0644]
winsup/cygwin/cygwait.h [new file with mode: 0644]
winsup/cygwin/exceptions.cc
winsup/cygwin/fhandler.cc
winsup/cygwin/fhandler_console.cc
winsup/cygwin/fhandler_dsp.cc
winsup/cygwin/fhandler_fifo.cc
winsup/cygwin/fhandler_serial.cc
winsup/cygwin/fhandler_tty.cc
winsup/cygwin/select.cc
winsup/cygwin/signal.cc
winsup/cygwin/sigproc.h
winsup/cygwin/thread.cc
winsup/cygwin/thread.h
winsup/cygwin/wait.cc

index 6bfb7ef676b2149617c12c23dc6cae3db885b7ff..ef885e08333df396b279552e1a002662a3b66468 100644 (file)
@@ -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
index a311256e26ab3d1253e4b781dc653db86b57cfc1..7bec42017d866c17bfd311113f7b29059d6e3e70 100644 (file)
@@ -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
index e65b44031824288f2b7eb2fed98430ec19622951..2aedb1c7b5c6531c72a7e5e1a4fe0962e6b30a56 100644 (file)
@@ -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 \
diff --git a/winsup/cygwin/cygwait.cc b/winsup/cygwin/cygwait.cc
new file mode 100644 (file)
index 0000000..6e0610d
--- /dev/null
@@ -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;
+}
diff --git a/winsup/cygwin/cygwait.h b/winsup/cygwin/cygwait.h
new file mode 100644 (file)
index 0000000..c2b7f58
--- /dev/null
@@ -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);
+}
index f78e8f7b6a55337387275a8af09c4c7d3ad08c85..3c22e35c3e0df585d71d6a03bb1205510fe6bcdf 100644 (file)
@@ -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;
index a22fe24963925f8732c2c59b80a68ab44c7f2466..55a73b66e901ef86594342d00641b8a5b7cdf199 100644 (file)
@@ -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:
index e54f11f2ae0d6782c905b3d8745cb413f26efa98..0208a4863425eebe437c75c2ddc63760e94a7750 100644 (file)
@@ -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*/
index 1cb3b465e3242298439c451250a4c6cf083d4741..b16606615d007a186bdd10a55ac781edf6d1a9b3 100644 (file)
@@ -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:
index 0e2d2bde4253755369ebb83d5006d4e78b73eb24..d2b236d5ca504d64db14d7a7f737729cd7302b27 100644 (file)
@@ -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 ();
index 033498742e03f55aed1e7a34cadaed65693fda14..c9a18c3d9ded3949625111e22f149ab9ab71979e 100644 (file)
@@ -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*/
index 38a0571cb52478a5d7d408c3202efc46a127cde0..fe7e283a921059545d0db54c35102f31eb3a59d7 100644 (file)
@@ -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*/
index 2d00e7c9603c6361c6a8b0578b7503179ab4f02c..0186af7336c3f0fcfd33684b11c541f42f4da1ea 100644 (file)
@@ -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*/
index 649cda694111888e2f34be4233db52784fe26de8..a62c038cddfe8da606e8a14a31e35b45938467a8 100644 (file)
@@ -22,6 +22,7 @@ details. */
 #include "fhandler.h"
 #include "dtable.h"
 #include "cygheap.h"
+#include "cygwait.h"
 
 #define _SA_NORESTART  0x8000
 
index a86c6bc42443ae06e711a656309d699cd6effc7f..d980f1a6e78aa1e6a5fe083aa3c6793e44e6bcb5 100644 (file)
@@ -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)));
index b66bd48352b60aae0d49c3029a7388688e30c69f..f3ff336f42439cf5be810976c1d9cd7c3f1ada00 100644 (file)
@@ -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--;
index ec3ca7ebf6bb9cb507c3e25919e3f6b416de4c2c..0dd9b893bd73e9855b4626ee94a13e1f9fcbe0cc 100644 (file)
@@ -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 ()
index 91a76239a752ef5d14e60ca2160c5258460358a2..829c123bd698220b5a9611caac802f5323f41059 100644 (file)
@@ -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);
 
This page took 0.060513 seconds and 5 git commands to generate.