]> sourceware.org Git - newlib-cygwin.git/commitdiff
* cygwait.cc (cancelable_wait): Mimic old cygwait behavior more closely wrt
authorChristopher Faylor <me@cgf.cx>
Tue, 19 Jun 2012 00:31:15 +0000 (00:31 +0000)
committerChristopher Faylor <me@cgf.cx>
Tue, 19 Jun 2012 00:31:15 +0000 (00:31 +0000)
handling of call_signal_handler.
* cygwait.h (WAIT_CANCELED): Move here and redefine.
(WAIT_SIGNALED): Ditto.
* thread.h (WAIT_CANCELED): Delete.
(WAIT_SIGNALED): Ditto.

20 files changed:
winsup/cygwin/ChangeLog
winsup/cygwin/cygserver_ipc.h
winsup/cygwin/cygthread.cc
winsup/cygwin/cygtls.h
winsup/cygwin/cygwait.cc
winsup/cygwin/cygwait.h
winsup/cygwin/dcrt0.cc
winsup/cygwin/exceptions.cc
winsup/cygwin/fhandler_socket.cc
winsup/cygwin/fhandler_tape.cc
winsup/cygwin/fhandler_termios.cc
winsup/cygwin/fhandler_tty.cc
winsup/cygwin/fhandler_windows.cc
winsup/cygwin/flock.cc
winsup/cygwin/posix_ipc.cc
winsup/cygwin/select.cc
winsup/cygwin/signal.cc
winsup/cygwin/sigproc.cc
winsup/cygwin/sigproc.h
winsup/cygwin/syscalls.cc

index 5a451abef15e2c7b2665df4046e9087ce8b87b63..9302d8b214b0ed1d80ca2d05d57cc59b197bb44d 100644 (file)
@@ -1,3 +1,12 @@
+2012-06-18  Christopher Faylor  <me.cygwin2012@cgf.cx>
+
+       * cygwait.cc (cancelable_wait): Mimic old cygwait behavior more closely
+       wrt handling of call_signal_handler.
+       * cygwait.h (WAIT_CANCELED): Move here and redefine.
+       (WAIT_SIGNALED): Ditto.
+       * thread.h (WAIT_CANCELED): Delete.
+       (WAIT_SIGNALED): Ditto.
+
 2012-06-18  Corinna Vinschen  <corinna@vinschen.de>
 
        * cygheap.cc (init_cygheap::init_installation_root): Rearrange code
index 2f7c3531feacdbc0e4e90e4c2129b1ea063bb3c8..31eea3464942538bfb8fd436c68c1f3f5294f2c4 100644 (file)
@@ -43,7 +43,7 @@ ipc_set_proc_info (proc &blk)
   blk.gidcnt = 0;
   blk.gidlist = NULL;
   blk.is_admin = false;
-  blk.signal_arrived = signal_arrived;
+  blk.signal_arrived = _my_tls.signal_arrived;
 }
 #endif /* __INSIDE_CYGWIN__ */
 
index 4cbd3b0647c01673beed3318749828dd79f2ceb9..604521c58c31faf438da84fab147a4b86d56efc4 100644 (file)
@@ -373,20 +373,16 @@ cygthread::detach (HANDLE sigwait)
          LONG prio = GetThreadPriority (hth);
          ::SetThreadPriority (hth, THREAD_PRIORITY_BELOW_NORMAL);
 
-         HANDLE w4[2];
-         unsigned n = 2;
          DWORD howlong = INFINITE;
-         w4[0] = sigwait;
-         w4[1] = signal_arrived;
          /* For a description of the below loop see the end of this file */
          for (int i = 0; i < 2; i++)
-           switch (res = WaitForMultipleObjects (n, w4, FALSE, howlong))
+           switch (res = cygwait (sigwait, howlong))
              {
              case WAIT_OBJECT_0:
                if (n == 1)
                  howlong = 50;
                break;
-             case WAIT_OBJECT_0 + 1:
+             case WAIT_SIGNALED:
                n = 1;
                if (i--)
                  howlong = 50;
@@ -395,20 +391,7 @@ cygthread::detach (HANDLE sigwait)
                break;
              default:
                if (!exiting)
-                 {
-                   system_printf ("WFMO failed waiting for cygthread '%s', %E", __name);
-                   for (unsigned j = 0; j < n; j++)
-                     switch (WaitForSingleObject (w4[j], 0))
-                       {
-                       case WAIT_OBJECT_0:
-                       case WAIT_TIMEOUT:
-                         break;
-                       default:
-                         system_printf ("%s handle %p is bad", (j ? "signal_arrived" : "semaphore"), w4[j]);
-                         break;
-                       }
-                   api_fatal ("exiting on fatal error");
-                 }
+                 api_fatal ("WFMO failed waiting for cygthread '%s', %E", __name);
                break;
              }
          /* WAIT_OBJECT_0 means that the thread successfully read something,
index 40c6151c2a908f7b27b826d6eeb8ca904b2c71d0..e4240984e3d30064da51eed1daca779e6ed64e4a 100644 (file)
@@ -174,7 +174,8 @@ public:
   int sa_flags;
   sigset_t oldmask;
   sigset_t deltamask;
-  HANDLE event;
+  HANDLE signal_arrived;
+  bool waiting;
   int *errno_addr;
   sigset_t sigmask;
   sigset_t sigwait_mask;
index 6e0610da0c560f22f7dedb3bec0d81777b99670e..377012a1a6acef7bc8688422886a2b73fd351039 100644 (file)
@@ -21,6 +21,8 @@
 
 #define is_cw_sig_handle       (mask & (is_cw_sig | is_cw_sig_eintr))
 
+TIMER_BASIC_INFORMATION cw_nowait;
+
 DWORD
 cancelable_wait (HANDLE object, PLARGE_INTEGER timeout, unsigned mask)
 {
index c2b7f58016124525cf3f49fe478feb11f9580ad6..a7daf88ebd040dc0f497cf35afdda85fd4252b30 100644 (file)
@@ -19,6 +19,8 @@ enum cw_wait_mask
   cw_sig_eintr =       0x0008
 };
 
+extern TIMER_BASIC_INFORMATION cw_nowait;
+
 const unsigned cw_std_mask = cw_cancel | cw_cancel_self | cw_sig;
 
 DWORD cancelable_wait (HANDLE, PLARGE_INTEGER timeout = NULL,
@@ -26,7 +28,7 @@ DWORD cancelable_wait (HANDLE, PLARGE_INTEGER timeout = NULL,
   __attribute__ ((regparm (3)));
 
 static inline DWORD __attribute__ ((always_inline))
-cygwait (HANDLE h, DWORD howlong = INFINITE)
+cancelable_wait (HANDLE h, DWORD howlong, unsigned mask)
 {
   PLARGE_INTEGER pli_howlong;
   LARGE_INTEGER li_howlong;
@@ -37,7 +39,14 @@ cygwait (HANDLE h, DWORD howlong = INFINITE)
       li_howlong.QuadPart = 10000ULL * howlong;
       pli_howlong = &li_howlong;
     }
-  return cancelable_wait (h, pli_howlong, cw_cancel | cw_sig_eintr);
+
+  return cancelable_wait (h, pi_howlong, mask);
+}
+
+static inline DWORD __attribute__ ((always_inline))
+cygwait (HANDLE h, DWORD howlong = INFINITE)
+{
+  return cancelable_wait (h, howlong, cw_cancel | cw_sig_eintr);
 }
 
 static inline DWORD __attribute__ ((always_inline))
@@ -45,3 +54,29 @@ cygwait (DWORD howlong)
 {
   return cygwait ((HANDLE) NULL, howlong);
 }
+
+class set_thread_waiting
+{
+  void doit (bool setit, DWORD& here)
+  {
+    if (setit)
+      {
+       if (_my_tls.signal_arrived == NULL)
+         _my_tls.signal_arrived = CreateEvent (&sec_none_nih, false, false, NULL);
+       here = _my_tls.signal_arrived;
+       _my_tls.waiting = true;
+      }
+  }
+public:
+  set_thread_waiting (bool setit, DWORD& here) { doit (setit, here); }
+  set_thread_waiting (DWORD& here) { doit (true, here); }
+
+  ~set_thread_waiting ()
+  {
+    if (_my_tls.waiting)
+      {
+       _my_tls.waiting = false;
+       ResetEvent (_my_tls.signal_arrived);
+      }
+  }
+};
index e28aecde9bf16ed8172318a0bb54ca5a4d9e780c..71b3d2ac3c1383f17e14d2e6c74230a40b12dd62 100644 (file)
@@ -842,8 +842,6 @@ dll_crt0_1 (void *)
   strace.microseconds ();
 #endif
 
-  create_signal_arrived (); /* FIXME: move into wait_sig? */
-
   /* Initialize debug muto, if DLL is built with --enable-debugging.
      Need to do this before any helper threads start. */
   debug_init ();
index 3c22e35c3e0df585d71d6a03bb1205510fe6bcdf..fe233cf497d6b8d723477213a056c3a64625052d 100644 (file)
@@ -715,7 +715,7 @@ handle_sigsuspend (sigset_t tempmask)
   sigproc_printf ("oldmask %p, newmask %p", oldmask, tempmask);
 
   pthread_testcancel ();
-  cancelable_wait (signal_arrived, NULL, cw_cancel | cw_cancel_self);
+  cancelable_wait (NULL, NULL, cw_cancel | cw_cancel_self | cw_sig_eintr);
 
   set_sig_errno (EINTR);       // Per POSIX
 
@@ -748,8 +748,7 @@ sig_handle_tty_stop (int sig)
   sigproc_printf ("process %d stopped by signal %d", myself->pid, sig);
   HANDLE w4[2];
   w4[0] = sigCONT;
-  w4[1] = signal_arrived;
-  switch (WaitForMultipleObjects (2, w4, TRUE, INFINITE))
+  switch (cancelable_wait (sigCONT, NULL, cw_sig_eintr))
     {
     case WAIT_OBJECT_0:
     case WAIT_OBJECT_0 + 1:
@@ -1248,7 +1247,7 @@ sigpacket::process ()
        {
          sigproc_printf ("default signal %d ignored", si.si_signo);
          if (continue_now)
-           SetEvent (signal_arrived);
+           SetEvent (use_tls->signal_arrived);
          goto done;
        }
 
index f780028010725a60bd9148201029f2794982376d..611e706195b28e45d0ed0289253c79cb60ab6615 100644 (file)
@@ -130,7 +130,7 @@ get_inet_addr (const struct sockaddr *in, int inlen,
          pthread_testcancel ();
          /* Using IsEventSignalled like this is racy since another thread could
             be waiting for signal_arrived. */
-         if (IsEventSignalled (signal_arrived)
+         if (cancelable_wait (NULL, cw_nowait, cw_sig_eintr) == WAIT_SIGNALED
              && !_my_tls.call_signal_handler ())
            {
              set_errno (EINTR);
@@ -662,7 +662,8 @@ fhandler_socket::wait_for_events (const long event_mask, const DWORD flags)
          return SOCKET_ERROR;
        }
 
-      WSAEVENT ev[2] = { wsock_evt, signal_arrived };
+      WSAEVENT ev[2] = { wsock_evt };
+      set_thread_waiting (ev[1]);
       switch (WSAWaitForMultipleEvents (2, ev, FALSE, 50, FALSE))
        {
          case WSA_WAIT_TIMEOUT:
@@ -1784,7 +1785,7 @@ fhandler_socket::close ()
          res = -1;
          break;
        }
-      if (WaitForSingleObject (signal_arrived, 10) == WAIT_OBJECT_0)
+      if (cygwait (10) == WAIT_SIGNALED)
        {
          set_errno (EINTR);
          res = -1;
index c394d862d227bf7c8c3238c29759687150796999..2e936c3b1462757f4ec2af94e3af07efbc7fc38a 100644 (file)
@@ -1142,26 +1142,14 @@ mtinfo::initialize ()
 inline bool
 fhandler_dev_tape::_lock (bool cancelable)
 {
-  HANDLE w4[3] = { mt_mtx, signal_arrived, NULL };
-  DWORD cnt = 2;
-  if (cancelable && (w4[2] = pthread::get_cancel_event ()) != NULL)
-    cnt = 3;
   /* O_NONBLOCK is only valid in a read or write call.  Only those are
      cancelable. */
   DWORD timeout = cancelable && is_nonblocking () ? 0 : INFINITE;
 restart:
-  switch (WaitForMultipleObjects (cnt, w4, FALSE, timeout))
+  switch (cancelable_wait (mt_mtx, timeout, cw_sig | cw_cancel | cw_cancel_self))
     {
     case WAIT_OBJECT_0:
       return true;
-    case WAIT_OBJECT_0 + 1:
-      if (_my_tls.call_signal_handler ())
-       goto restart;
-      set_errno (EINTR);
-      return false;
-    case WAIT_OBJECT_0 + 2:
-      pthread::static_cancel_self ();
-      /*NOTREACHED*/
     case WAIT_TIMEOUT:
       set_errno (EAGAIN);
       return false;
index 7fddba5b3fc045b76fc332a1b4946d244a480713..3bfa38a6b10a43af18eb0d5e0e93e7db59f34fa5 100644 (file)
@@ -204,7 +204,7 @@ fhandler_termios::bg_check (int sig)
     {
       /* Don't raise a SIGTT* signal if we have already been
         interrupted by another signal. */
-      if (WaitForSingleObject (signal_arrived, 0) != WAIT_OBJECT_0)
+      if (cygwait (0) != WAIT_SIGNALED)
        {
          siginfo_t si = {0};
          si.si_signo = sig;
index fe7e283a921059545d0db54c35102f31eb3a59d7..c5f1d46183cdf23668c4d4438b68c9d4a33f569c 100644 (file)
@@ -281,7 +281,7 @@ fhandler_pty_master::process_slave_output (char *buf, size_t len, int pktmode_on
              goto out;
            }
          pthread_testcancel ();
-         if (WaitForSingleObject (signal_arrived, 10) == WAIT_OBJECT_0
+         if (cancelable_wait (NULL, 10, cw_sig_eintr) == WAIT_SIGNALED
              && !_my_tls.call_signal_handler ())
            {
              set_errno (EINTR);
index c89d98e1649040532e781e2f597acbf539e63095..b592e3217c30ac4b4bfd6d7831207a3a024f7719 100644 (file)
@@ -96,7 +96,8 @@ fhandler_windows::read (void *buf, size_t& len)
       return;
     }
 
-  HANDLE w4[3] = { get_handle (), signal_arrived, NULL };
+  HANDLE w4[3] = { get_handle (), };
+  set_thread_waiting (w4[1]);
   DWORD cnt = 2;
   if ((w4[cnt] = pthread::get_cancel_event ()) != NULL)
     ++cnt;
index 176e4869efd3f60fe6d4a9603e70907fa684211e..f40c1e5c6fe408e7f6983297a0fab63d3a03b575 100644 (file)
@@ -1247,7 +1247,7 @@ lf_setlock (lockf_t *lock, inode_t *node, lockf_t **clean, HANDLE fhdl)
        timeout = 100L;
 
       DWORD WAIT_SIGNAL_ARRIVED = WAIT_OBJECT_0 + wait_count;
-      w4[wait_count++] = signal_arrived;
+      set_thread_waiting (w4[wait_count++]);
 
       DWORD WAIT_THREAD_CANCELED = WAIT_TIMEOUT + 1;
       HANDLE cancel_event = pthread::get_cancel_event ();
index b9d224e43ccec6b7aa3274432b118f0489f53567..b427d11d6a4d47d418b80b4dbf3e7c332f8d8458 100644 (file)
@@ -119,14 +119,12 @@ ipc_mutex_init (HANDLE *pmtx, const char *name)
 static int
 ipc_mutex_lock (HANDLE mtx)
 {
-  HANDLE h[2] = { mtx, signal_arrived };
-
-  switch (WaitForMultipleObjects (2, h, FALSE, INFINITE))
+  switch (cancelable_wait (mtx, NULL, cw_sig_eintr | cw_cancel | cw_cancel_self))
     {
     case WAIT_OBJECT_0:
     case WAIT_ABANDONED_0:
       return 0;
-    case WAIT_OBJECT_0 + 1:
+    case WAIT_SIGNALED:
       set_errno (EINTR);
       return 1;
     default:
@@ -174,11 +172,12 @@ ipc_cond_init (HANDLE *pevt, const char *name, char sr)
 static int
 ipc_cond_timedwait (HANDLE evt, HANDLE mtx, const struct timespec *abstime)
 {
-  HANDLE w4[4] = { evt, signal_arrived, NULL, NULL };
+  HANDLE w4[4] = { evt, };
   DWORD cnt = 2;
   DWORD timer_idx = 0;
   int ret = 0;
 
+  set_thread_waiting (w4[1]);
   if ((w4[cnt] = pthread::get_cancel_event ()) != NULL)
     ++cnt;
   if (abstime)
index 0186af7336c3f0fcfd33684b11c541f42f4da1ea..d98e132555f4757eeede3e7e4a64122cf857f906 100644 (file)
@@ -312,7 +312,7 @@ select_stuff::wait (fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
   select_record *s = &start;
   DWORD m = 0;
 
-  w4[m++] = signal_arrived;  /* Always wait for the arrival of a signal. */
+  set_thread_waiting (w4[m++]);
   if ((w4[m] = pthread::get_cancel_event ()) != NULL)
     m++;
 
index a62c038cddfe8da606e8a14a31e35b45938467a8..595bb01d705de01d81860c4731762f6dab158293 100644 (file)
@@ -120,12 +120,9 @@ clock_nanosleep (clockid_t clk_id, int flags, const struct timespec *rqtp,
 
   syscall_printf ("clock_nanosleep (%ld.%09ld)", rqtp->tv_sec, rqtp->tv_nsec);
 
-  int rc = cancelable_wait (signal_arrived, &timeout);
-  if (rc == WAIT_OBJECT_0)
-    {
-      _my_tls.call_signal_handler ();
-      res = EINTR;
-    }
+  int rc = cancelable_wait (NULL, &timeout, cw_sig | cw_cancel | cw_cancel_self);
+  if (rc == WAIT_SIGNALED)
+    res = EINTR;
 
   /* according to POSIX, rmtp is used only if !abstime */
   if (rmtp && !abstime)
@@ -565,21 +562,14 @@ extern "C" int
 sigwaitinfo (const sigset_t *set, siginfo_t *info)
 {
   pthread_testcancel ();
-  HANDLE h;
-  h = _my_tls.event = CreateEvent (&sec_none_nih, FALSE, FALSE, NULL);
-  if (!h)
-    {
-      __seterrno ();
-      return -1;
-    }
 
   _my_tls.sigwait_mask = *set;
   sig_dispatch_pending (true);
 
   int res;
-  switch (WaitForSingleObject (h, INFINITE))
+  switch (cancelable_wait (NULL, NULL, cw_sig | cw_cancel | cw_cancel_self))
     {
-    case WAIT_OBJECT_0:
+    case WAIT_SIGNALED:
       if (!sigismember (set, _my_tls.infodata.si_signo))
        {
          set_errno (EINTR);
@@ -598,8 +588,6 @@ sigwaitinfo (const sigset_t *set, siginfo_t *info)
       res = -1;
     }
 
-  _my_tls.event = NULL;
-  CloseHandle (h);
   sigproc_printf ("returning signal %d", res);
   return res;
 }
index 05d98729ff6bc951739e6bcc64c93756ccc69639..56fce16639d32fb71c71c44a5613ff46c3afc42b 100644 (file)
@@ -43,9 +43,6 @@ int __sp_ln;
 
 char NO_COPY myself_nowait_dummy[1] = {'0'};// Flag to sig_send that signal goes to
                                        //  current process but no wait is required
-HANDLE NO_COPY signal_arrived;         // Event signaled when a signal has
-                                       //  resulted in a user-specified
-                                       //  function call
 
 #define Static static NO_COPY
 
@@ -518,17 +515,6 @@ sig_dispatch_pending (bool fast)
     sig_send (myself, fast ? __SIGFLUSHFAST : __SIGFLUSH);
 }
 
-void __stdcall
-create_signal_arrived ()
-{
-  if (signal_arrived)
-    return;
-  /* local event signaled when main thread has been dispatched
-     to a signal handler function. */
-  signal_arrived = CreateEvent (&sec_none_nih, false, false, NULL);
-  ProtectHandle (signal_arrived);
-}
-
 /* Signal thread initialization.  Called from dll_crt0_1.
    This routine starts the signal handling thread.  */
 void __stdcall
index d980f1a6e78aa1e6a5fe083aa3c6793e44e6bcb5..ba8a231b9285488087081b75542d3ebd9cae6e7f 100644 (file)
@@ -58,7 +58,6 @@ struct sigpacket
   int __stdcall process () __attribute__ ((regparm (1)));
 };
 
-extern HANDLE signal_arrived;
 extern HANDLE sigCONT;
 
 void __stdcall sig_dispatch_pending (bool fast = false);
@@ -86,7 +85,6 @@ int __stdcall sig_send (_pinfo *, siginfo_t&, class _cygtls *tls = NULL) __attri
 int __stdcall sig_send (_pinfo *, int) __attribute__ ((regparm (2)));
 void __stdcall signal_fixup_after_exec ();
 void __stdcall sigalloc ();
-void __stdcall create_signal_arrived ();
 
 int kill_pgrp (pid_t, siginfo_t&);
 int killsys (pid_t, int);
index 2077a0a3c282524dd82ab3561f34c3f4c6e04a08..c0cacac9730c686134191b0d925124b604fbccbb 100644 (file)
@@ -2295,7 +2295,7 @@ retry:
     {
       debug_printf ("status %p", status);
       if (status == STATUS_SHARING_VIOLATION
-         && WaitForSingleObject (signal_arrived, 10L) != WAIT_OBJECT_0)
+         && cygwait (10L) != WAIT_SIGNALED)
        {
          /* Typical BLODA problem.  Some virus scanners check newly generated
             files and while doing that disallow DELETE access.  That's really
This page took 0.059934 seconds and 5 git commands to generate.