* 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.
This commit is contained in:
parent
6c1f4d7d64
commit
16efa64721
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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, ¤tvalue))
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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 ();
|
||||
|
||||
|
|
Loading…
Reference in New Issue