mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-12-28 00:16:15 +01:00
win32: Add 'shared' support to SRWLock emulation
This commit is contained in:
parent
9f42e3be1b
commit
2539bd007d
@ -106,6 +106,9 @@ typedef struct
|
|||||||
void (__stdcall * AcquireSRWLockExclusive) (gpointer lock);
|
void (__stdcall * AcquireSRWLockExclusive) (gpointer lock);
|
||||||
BOOLEAN (__stdcall * TryAcquireSRWLockExclusive) (gpointer lock);
|
BOOLEAN (__stdcall * TryAcquireSRWLockExclusive) (gpointer lock);
|
||||||
void (__stdcall * ReleaseSRWLockExclusive) (gpointer lock);
|
void (__stdcall * ReleaseSRWLockExclusive) (gpointer lock);
|
||||||
|
void (__stdcall * AcquireSRWLockShared) (gpointer lock);
|
||||||
|
BOOLEAN (__stdcall * TryAcquireSRWLockShared) (gpointer lock);
|
||||||
|
void (__stdcall * ReleaseSRWLockShared) (gpointer lock);
|
||||||
|
|
||||||
void (__stdcall * InitializeConditionVariable) (gpointer cond);
|
void (__stdcall * InitializeConditionVariable) (gpointer cond);
|
||||||
void (__stdcall * DeleteConditionVariable) (gpointer cond); /* fake */
|
void (__stdcall * DeleteConditionVariable) (gpointer cond); /* fake */
|
||||||
@ -522,6 +525,12 @@ g_thread_xp_CallThisOnThreadExit (void)
|
|||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
CRITICAL_SECTION writer_lock;
|
CRITICAL_SECTION writer_lock;
|
||||||
|
gboolean ever_shared; /* protected by writer_lock */
|
||||||
|
|
||||||
|
/* below is only ever touched if ever_shared becomes true */
|
||||||
|
CRITICAL_SECTION atomicity;
|
||||||
|
GThreadXpWaiter *queued_writer; /* protected by atomicity lock */
|
||||||
|
gint num_readers; /* protected by atomicity lock */
|
||||||
} GThreadSRWLock;
|
} GThreadSRWLock;
|
||||||
|
|
||||||
static void __stdcall
|
static void __stdcall
|
||||||
@ -537,6 +546,9 @@ g_thread_xp_DeleteSRWLock (gpointer mutex)
|
|||||||
|
|
||||||
if (lock)
|
if (lock)
|
||||||
{
|
{
|
||||||
|
if (lock->ever_shared)
|
||||||
|
DeleteCriticalSection (&lock->atomicity);
|
||||||
|
|
||||||
DeleteCriticalSection (&lock->writer_lock);
|
DeleteCriticalSection (&lock->writer_lock);
|
||||||
free (lock);
|
free (lock);
|
||||||
}
|
}
|
||||||
@ -564,6 +576,7 @@ g_thread_xp_get_srwlock (GThreadSRWLock * volatile *lock)
|
|||||||
g_thread_abort (errno, "malloc");
|
g_thread_abort (errno, "malloc");
|
||||||
|
|
||||||
InitializeCriticalSection (&result->writer_lock);
|
InitializeCriticalSection (&result->writer_lock);
|
||||||
|
result->ever_shared = FALSE;
|
||||||
*lock = result;
|
*lock = result;
|
||||||
|
|
||||||
LeaveCriticalSection (&g_thread_xp_lock);
|
LeaveCriticalSection (&g_thread_xp_lock);
|
||||||
@ -578,6 +591,21 @@ g_thread_xp_AcquireSRWLockExclusive (gpointer mutex)
|
|||||||
GThreadSRWLock *lock = g_thread_xp_get_srwlock (mutex);
|
GThreadSRWLock *lock = g_thread_xp_get_srwlock (mutex);
|
||||||
|
|
||||||
EnterCriticalSection (&lock->writer_lock);
|
EnterCriticalSection (&lock->writer_lock);
|
||||||
|
|
||||||
|
if (lock->ever_shared)
|
||||||
|
{
|
||||||
|
GThreadXpWaiter *waiter = NULL;
|
||||||
|
|
||||||
|
EnterCriticalSection (&lock->atomicity);
|
||||||
|
if (lock->num_readers > 0)
|
||||||
|
lock->queued_writer = waiter = g_thread_xp_waiter_get ();
|
||||||
|
LeaveCriticalSection (&lock->atomicity);
|
||||||
|
|
||||||
|
if (waiter != NULL)
|
||||||
|
WaitForSingleObject (waiter->event, INFINITE);
|
||||||
|
|
||||||
|
lock->queued_writer = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOLEAN __stdcall
|
static BOOLEAN __stdcall
|
||||||
@ -588,6 +616,21 @@ g_thread_xp_TryAcquireSRWLockExclusive (gpointer mutex)
|
|||||||
if (!TryEnterCriticalSection (&lock->writer_lock))
|
if (!TryEnterCriticalSection (&lock->writer_lock))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
if (lock->ever_shared)
|
||||||
|
{
|
||||||
|
gboolean available;
|
||||||
|
|
||||||
|
EnterCriticalSection (&lock->atomicity);
|
||||||
|
available = lock->num_readers == 0;
|
||||||
|
LeaveCriticalSection (&lock->atomicity);
|
||||||
|
|
||||||
|
if (!available)
|
||||||
|
{
|
||||||
|
LeaveCriticalSection (&lock->writer_lock);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -603,6 +646,65 @@ g_thread_xp_ReleaseSRWLockExclusive (gpointer mutex)
|
|||||||
LeaveCriticalSection (&lock->writer_lock);
|
LeaveCriticalSection (&lock->writer_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
g_thread_xp_srwlock_become_reader (GThreadSRWLock *lock)
|
||||||
|
{
|
||||||
|
if G_UNLIKELY (!lock->ever_shared)
|
||||||
|
{
|
||||||
|
InitializeCriticalSection (&lock->atomicity);
|
||||||
|
lock->queued_writer = NULL;
|
||||||
|
lock->num_readers = 0;
|
||||||
|
|
||||||
|
lock->ever_shared = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
EnterCriticalSection (&lock->atomicity);
|
||||||
|
lock->num_readers++;
|
||||||
|
LeaveCriticalSection (&lock->atomicity);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __stdcall
|
||||||
|
g_thread_xp_AcquireSRWLockShared (gpointer mutex)
|
||||||
|
{
|
||||||
|
GThreadSRWLock *lock = g_thread_xp_get_srwlock (mutex);
|
||||||
|
|
||||||
|
EnterCriticalSection (&lock->writer_lock);
|
||||||
|
|
||||||
|
g_thread_xp_srwlock_become_reader (lock);
|
||||||
|
|
||||||
|
LeaveCriticalSection (&lock->writer_lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
static BOOLEAN __stdcall
|
||||||
|
g_thread_xp_TryAcquireSRWLockShared (gpointer mutex)
|
||||||
|
{
|
||||||
|
GThreadSRWLock *lock = g_thread_xp_get_srwlock (mutex);
|
||||||
|
|
||||||
|
if (!TryEnterCriticalSection (&lock->writer_lock))
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
g_thread_xp_srwlock_become_reader (lock);
|
||||||
|
|
||||||
|
LeaveCriticalSection (&lock->writer_lock);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __stdcall
|
||||||
|
g_thread_xp_ReleaseSRWLockShared (gpointer mutex)
|
||||||
|
{
|
||||||
|
GThreadSRWLock *lock = g_thread_xp_get_srwlock (mutex);
|
||||||
|
|
||||||
|
EnterCriticalSection (&lock->atomicity);
|
||||||
|
|
||||||
|
lock->num_readers--;
|
||||||
|
|
||||||
|
if (lock->num_readers == 0 && lock->queued_writer)
|
||||||
|
SetEvent (lock->queued_writer->event);
|
||||||
|
|
||||||
|
LeaveCriticalSection (&lock->atomicity);
|
||||||
|
}
|
||||||
|
|
||||||
/* {{{2 CONDITION_VARIABLE emulation */
|
/* {{{2 CONDITION_VARIABLE emulation */
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
@ -738,6 +840,9 @@ g_thread_xp_init (void)
|
|||||||
g_thread_xp_AcquireSRWLockExclusive,
|
g_thread_xp_AcquireSRWLockExclusive,
|
||||||
g_thread_xp_TryAcquireSRWLockExclusive,
|
g_thread_xp_TryAcquireSRWLockExclusive,
|
||||||
g_thread_xp_ReleaseSRWLockExclusive,
|
g_thread_xp_ReleaseSRWLockExclusive,
|
||||||
|
g_thread_xp_AcquireSRWLockShared,
|
||||||
|
g_thread_xp_TryAcquireSRWLockShared,
|
||||||
|
g_thread_xp_ReleaseSRWLockShared,
|
||||||
g_thread_xp_InitializeConditionVariable,
|
g_thread_xp_InitializeConditionVariable,
|
||||||
g_thread_xp_DeleteConditionVariable,
|
g_thread_xp_DeleteConditionVariable,
|
||||||
g_thread_xp_SleepConditionVariableSRW,
|
g_thread_xp_SleepConditionVariableSRW,
|
||||||
@ -786,6 +891,9 @@ g_thread_lookup_native_funcs (void)
|
|||||||
GET_FUNC(AcquireSRWLockExclusive);
|
GET_FUNC(AcquireSRWLockExclusive);
|
||||||
GET_FUNC(TryAcquireSRWLockExclusive);
|
GET_FUNC(TryAcquireSRWLockExclusive);
|
||||||
GET_FUNC(ReleaseSRWLockExclusive);
|
GET_FUNC(ReleaseSRWLockExclusive);
|
||||||
|
GET_FUNC(AcquireSRWLockShared);
|
||||||
|
GET_FUNC(TryAcquireSRWLockShared);
|
||||||
|
GET_FUNC(ReleaseSRWLockShared);
|
||||||
|
|
||||||
GET_FUNC(InitializeConditionVariable);
|
GET_FUNC(InitializeConditionVariable);
|
||||||
GET_FUNC(SleepConditionVariableSRW);
|
GET_FUNC(SleepConditionVariableSRW);
|
||||||
|
Loading…
Reference in New Issue
Block a user