Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/winsup
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2013-07-23 18:15:20 +0400
committerCorinna Vinschen <corinna@vinschen.de>2013-07-23 18:15:20 +0400
commit16efa64721b0dd9cfc699ce4b3928a8e7644b980 (patch)
treec345d7373cd6b5e3f8fd3ce559ff2211a7d7f534 /winsup
parent6c1f4d7d644d6199f5ecc6c542addda657cad600 (diff)
* 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.
Diffstat (limited to 'winsup')
-rw-r--r--winsup/cygwin/ChangeLog23
-rw-r--r--winsup/cygwin/ntdll.h14
-rw-r--r--winsup/cygwin/thread.cc58
-rw-r--r--winsup/cygwin/thread.h6
4 files changed, 74 insertions, 27 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 8990fbab9..0d20106bc 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,5 +1,28 @@
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.
2013-07-22 Corinna Vinschen <corinna@vinschen.de>
diff --git a/winsup/cygwin/ntdll.h b/winsup/cygwin/ntdll.h
index 2582bf25f..c67a775ec 100644
--- a/winsup/cygwin/ntdll.h
+++ b/winsup/cygwin/ntdll.h
@@ -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);
diff --git a/winsup/cygwin/thread.cc b/winsup/cygwin/thread.cc
index 450888d91..0256ad717 100644
--- a/winsup/cygwin/thread.cc
+++ b/winsup/cygwin/thread.cc
@@ -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);
@@ -3524,18 +3516,30 @@ semaphore::_wait ()
}
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);
}
}
diff --git a/winsup/cygwin/thread.h b/winsup/cygwin/thread.h
index c87c620eb..badffcb79 100644
--- a/winsup/cygwin/thread.h
+++ b/winsup/cygwin/thread.h
@@ -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 ();