]> sourceware.org Git - newlib-cygwin.git/commitdiff
* ntdll.h (struct _SEMAPHORE_BASIC_INFORMATION): Define.
authorCorinna Vinschen <corinna@vinschen.de>
Tue, 23 Jul 2013 14:15:20 +0000 (14:15 +0000)
committerCorinna Vinschen <corinna@vinschen.de>
Tue, 23 Jul 2013 14:15:20 +0000 (14:15 +0000)
(enum _SEMAPHORE_INFORMATION_CLASS): Define.
(NtQuerySemaphore): Declare.
* thread.h (class semaphore): Add member startvalue.
(semaphore::fixup_before_fork): New inline method.
(semaphore::_fixup_before_fork): Declare.
* thread.cc (MTinterface::fixup_before_fork): Additionally call
semaphore::fixup_before_fork.
(semaphore::semaphore): Set currentvalue to -1.  Set startvalue to
incoming initializer value.
(semaphore::_getvalue): Just query semaphore using NtQuerySemaphore
rather then using WFSO/Release.
(semaphore::_post): Drop setting currentvalue.  It's not thread-safe.
(semaphore::_trywait): Ditto.
(semaphore::_timedwait): Ditto.
(semaphore::_wait): Ditto.
(semaphore::_fixup_before_fork): New method, setting currentvalue from
actual windows semaphore right before fork.
(semaphore::_fixup_after_fork): Drop kludge from 2013-07-10.  Drop
FIXME comment.

winsup/cygwin/ChangeLog
winsup/cygwin/ntdll.h
winsup/cygwin/thread.cc
winsup/cygwin/thread.h

index 8990fbab9ead2be4e6b736eaf7654fa32cc13cf3..0d20106bc780252f9d21ad5d317fe5ed7a40359e 100644 (file)
@@ -1,3 +1,26 @@
+2013-07-23  Corinna Vinschen  <corinna@vinschen.de>
+
+       * ntdll.h (struct _SEMAPHORE_BASIC_INFORMATION): Define.
+       (enum _SEMAPHORE_INFORMATION_CLASS): Define.
+       (NtQuerySemaphore): Declare.
+       * thread.h (class semaphore): Add member startvalue.
+       (semaphore::fixup_before_fork): New inline method.
+       (semaphore::_fixup_before_fork): Declare.
+       * thread.cc (MTinterface::fixup_before_fork): Additionally call
+       semaphore::fixup_before_fork.
+       (semaphore::semaphore): Set currentvalue to -1.  Set startvalue to
+       incoming initializer value.
+       (semaphore::_getvalue): Just query semaphore using NtQuerySemaphore
+       rather then using WFSO/Release.
+       (semaphore::_post): Drop setting currentvalue.  It's not thread-safe.
+       (semaphore::_trywait): Ditto.
+       (semaphore::_timedwait): Ditto.
+       (semaphore::_wait): Ditto.
+       (semaphore::_fixup_before_fork): New method, setting currentvalue from
+       actual windows semaphore right before fork.
+       (semaphore::_fixup_after_fork): Drop kludge from 2013-07-10.  Drop
+       FIXME comment.
+
 2013-07-23  Corinna Vinschen  <corinna@vinschen.de>
 
        * cygtls.cc (well_known_dlls): Add kernelbase.dll.
index 2582bf25febb126d98c000451a81e5e736fd1973..c67a775ec5e4bb9a19b26e8e30dd9d6b391daf7f 100644 (file)
@@ -1102,6 +1102,18 @@ typedef enum _EVENT_INFORMATION_CLASS
   EventBasicInformation = 0
 } EVENT_INFORMATION_CLASS, *PEVENT_INFORMATION_CLASS;
 
+/* Checked on 64 bit. */
+typedef struct _SEMAPHORE_BASIC_INFORMATION
+{
+  LONG CurrentCount;
+  LONG MaximumCount;
+} SEMAPHORE_BASIC_INFORMATION, *PSEMAPHORE_BASIC_INFORMATION;
+
+typedef enum _SEMAPHORE_INFORMATION_CLASS
+{
+  SemaphoreBasicInformation = 0
+} SEMAPHORE_INFORMATION_CLASS, *PSEMAPHORE_INFORMATION_CLASS;
+
 typedef enum _THREAD_INFORMATION_CLASS
 {
   ThreadBasicInformation = 0,
@@ -1275,6 +1287,8 @@ extern "C"
                                          PVOID, ULONG, PULONG);
   NTSTATUS NTAPI NtQueryObject (HANDLE, OBJECT_INFORMATION_CLASS, VOID *,
                                ULONG, ULONG *);
+  NTSTATUS NTAPI NtQuerySemaphore (HANDLE, SEMAPHORE_INFORMATION_CLASS,
+                                  PVOID, ULONG, PULONG);
   NTSTATUS NTAPI NtQuerySystemInformation (SYSTEM_INFORMATION_CLASS,
                                           PVOID, ULONG, PULONG);
   NTSTATUS WINAPI NtQuerySystemTime (PLARGE_INTEGER);
index 450888d91937c525dbd86ac48c997eac4d1d27b0..0256ad717efd5033ea719ebc4e596bff6364c5df 100644 (file)
@@ -316,6 +316,7 @@ void
 MTinterface::fixup_before_fork ()
 {
   pthread_key::fixup_before_fork ();
+  semaphore::fixup_before_fork ();
 }
 
 /* This function is called from a single threaded process */
@@ -3376,7 +3377,8 @@ List<semaphore> semaphore::semaphores;
 semaphore::semaphore (int pshared, unsigned int value)
 : verifyable_object (SEM_MAGIC),
   shared (pshared),
-  currentvalue (value),
+  currentvalue (-1),
+  startvalue (value),
   fd (-1),
   hash (0ULL),
   sem (NULL)
@@ -3394,7 +3396,8 @@ semaphore::semaphore (unsigned long long shash, LUID sluid, int sfd,
                      sem_t *ssem, int oflag, mode_t mode, unsigned int value)
 : verifyable_object (SEM_MAGIC),
   shared (PTHREAD_PROCESS_SHARED),
-  currentvalue (value),                /* Unused for named semaphores. */
+  currentvalue (-1),           /* Unused for named semaphores. */
+  startvalue (value),
   fd (sfd),
   hash (shash),
   luid (sluid),
@@ -3428,29 +3431,21 @@ semaphore::~semaphore ()
 void
 semaphore::_post ()
 {
-  if (ReleaseSemaphore (win32_obj_id, 1, &currentvalue))
-    currentvalue++;
+  LONG dummy;
+  ReleaseSemaphore (win32_obj_id, 1, &dummy);
 }
 
 int
 semaphore::_getvalue (int *sval)
 {
-  LONG val;
+  NTSTATUS status;
+  SEMAPHORE_BASIC_INFORMATION sbi;
 
-  switch (WaitForSingleObject (win32_obj_id, 0))
-    {
-      case WAIT_OBJECT_0:
-       ReleaseSemaphore (win32_obj_id, 1, &val);
-       *sval = val + 1;
-       break;
-      case WAIT_TIMEOUT:
-       *sval = 0;
-       break;
-      default:
-       set_errno (EAGAIN);
-       return -1;
-    }
-  return 0;
+  status = NtQuerySemaphore (win32_obj_id, SemaphoreBasicInformation, &sbi,
+                            sizeof sbi, NULL);
+  if (NT_SUCCESS (status))
+    return sbi.CurrentCount;
+  return startvalue;
 }
 
 int
@@ -3463,7 +3458,6 @@ semaphore::_trywait ()
       set_errno (EAGAIN);
       return -1;
     }
-  currentvalue--;
   return 0;
 }
 
@@ -3489,7 +3483,6 @@ semaphore::_timedwait (const struct timespec *abstime)
   switch (cygwait (win32_obj_id, &timeout, cw_cancel | cw_cancel_self | cw_sig_eintr))
     {
     case WAIT_OBJECT_0:
-      currentvalue--;
       break;
     case WAIT_SIGNALED:
       set_errno (EINTR);
@@ -3511,7 +3504,6 @@ semaphore::_wait ()
   switch (cygwait (win32_obj_id, cw_infinite, cw_cancel | cw_cancel_self | cw_sig_eintr))
     {
     case WAIT_OBJECT_0:
-      currentvalue--;
       break;
     case WAIT_SIGNALED:
       set_errno (EINTR);
@@ -3523,19 +3515,31 @@ semaphore::_wait ()
   return 0;
 }
 
+void
+semaphore::_fixup_before_fork ()
+{
+  NTSTATUS status;
+  SEMAPHORE_BASIC_INFORMATION sbi;
+
+  status = NtQuerySemaphore (win32_obj_id, SemaphoreBasicInformation, &sbi,
+                            sizeof sbi, NULL);
+  if (NT_SUCCESS (status))
+    currentvalue = sbi.CurrentCount;
+  else
+    currentvalue = startvalue;
+}
+
 void
 semaphore::_fixup_after_fork ()
 {
   if (shared == PTHREAD_PROCESS_PRIVATE)
     {
       pthread_printf ("sem %p", this);
-      if (!currentvalue)
-       currentvalue = 1;
-      /* FIXME: duplicate code here and in the constructor. */
       win32_obj_id = ::CreateSemaphore (&sec_none_nih, currentvalue,
-                                             INT32_MAX, NULL);
+                                       INT32_MAX, NULL);
       if (!win32_obj_id)
-       api_fatal ("failed to create new win32 semaphore, currentvalue %ld, %E", currentvalue);
+       api_fatal ("failed to create new win32 semaphore, "
+                  "currentvalue %ld, %E", currentvalue);
     }
 }
 
index c87c620ebdac34f3c7e1a3162260396b31fc0b5b..badffcb797ba862f2eb228242cae9e479d1c4006 100644 (file)
@@ -638,6 +638,7 @@ public:
   HANDLE win32_obj_id;
   int shared;
   LONG currentvalue;
+  LONG startvalue;
   int fd;
   unsigned long long hash;
   LUID luid;
@@ -648,6 +649,10 @@ public:
   ~semaphore ();
 
   class semaphore * next;
+  static void fixup_before_fork ()
+  {
+    semaphores.for_each (&semaphore::_fixup_before_fork);
+  }
   static void fixup_after_fork ()
   {
     semaphores.fixup_after_fork ();
@@ -666,6 +671,7 @@ private:
   int _trywait ();
   int _timedwait (const struct timespec *abstime);
 
+  void _fixup_before_fork ();
   void _fixup_after_fork ();
   void _terminate ();
 
This page took 0.043865 seconds and 5 git commands to generate.