>From 4570a616244efbc2fa4bd8788f27ef0e4b48bdbe Mon Sep 17 00:00:00 2001 From: Bruno Haible
Date: Thu, 20 Jun 2019 04:10:39 +0200 Subject: [PATCH 10/26] windows-recmutex: New module. * lib/windows-recmutex.h: New file, extracted from lib/glthread/lock.h. * lib/windows-recmutex.c: New file, extracted from lib/glthread/lock.c. * lib/glthread/lock.h: Include windows-recmutex.h. (gl_recursive_lock_t): Define using glwthread_recmutex_t. (gl_recursive_lock_initializer): Define using GLWTHREAD_RECMUTEX_INIT. (glthread_recursive_lock_init): Define using glwthread_recmutex_init. (glthread_recursive_lock_lock): Define using glwthread_recmutex_lock. (glthread_recursive_lock_unlock): Define using glwthread_recmutex_unlock. (glthread_recursive_lock_destroy): Define using glwthread_recmutex_destroy. (glthread_recursive_lock_init_func, glthread_recursive_lock_lock_func, glthread_recursive_lock_unlock_func, glthread_recursive_lock_destroy_func): Remove declarations. * lib/glthread/lock.c (glthread_recursive_lock_init_func, glthread_recursive_lock_lock_func, glthread_recursive_lock_unlock_func, glthread_recursive_lock_destroy_func): Remove functions. * modules/windows-recmutex: New file. * modules/lock (Depends-on): Add windows-recmutex. --- ChangeLog | 23 +++++++++ lib/glthread/lock.c | 70 -------------------------- lib/glthread/lock.h | 28 +++-------- lib/windows-recmutex.c | 127 +++++++++++++++++++++++++++++++++++++++++++++++ lib/windows-recmutex.h | 57 +++++++++++++++++++++ modules/lock | 5 +- modules/windows-recmutex | 28 +++++++++++ 7 files changed, 245 insertions(+), 93 deletions(-) create mode 100644 lib/windows-recmutex.c create mode 100644 lib/windows-recmutex.h create mode 100644 modules/windows-recmutex diff --git a/ChangeLog b/ChangeLog index a168b23..1ac5490 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,28 @@ 2019-06-20 Bruno Haible + windows-recmutex: New module. + * lib/windows-recmutex.h: New file, extracted from lib/glthread/lock.h. + * lib/windows-recmutex.c: New file, extracted from lib/glthread/lock.c. + * lib/glthread/lock.h: Include windows-recmutex.h. + (gl_recursive_lock_t): Define using glwthread_recmutex_t. + (gl_recursive_lock_initializer): Define using GLWTHREAD_RECMUTEX_INIT. + (glthread_recursive_lock_init): Define using glwthread_recmutex_init. + (glthread_recursive_lock_lock): Define using glwthread_recmutex_lock. + (glthread_recursive_lock_unlock): Define using + glwthread_recmutex_unlock. + (glthread_recursive_lock_destroy): Define using + glwthread_recmutex_destroy. + (glthread_recursive_lock_init_func, glthread_recursive_lock_lock_func, + glthread_recursive_lock_unlock_func, + glthread_recursive_lock_destroy_func): Remove declarations. + * lib/glthread/lock.c (glthread_recursive_lock_init_func, + glthread_recursive_lock_lock_func, glthread_recursive_lock_unlock_func, + glthread_recursive_lock_destroy_func): Remove functions. + * modules/windows-recmutex: New file. + * modules/lock (Depends-on): Add windows-recmutex. + +2019-06-20 Bruno Haible + windows-mutex: New module. * lib/windows-mutex.h: New file, extracted from lib/glthread/lock.h. * lib/windows-mutex.c: New file, extracted from lib/glthread/lock.c. diff --git a/lib/glthread/lock.c b/lib/glthread/lock.c index e17f524..a686a30 100644 --- a/lib/glthread/lock.c +++ b/lib/glthread/lock.c @@ -1073,76 +1073,6 @@ glthread_rwlock_destroy_func (gl_rwlock_t *lock) return 0; } -/* --------------------- gl_recursive_lock_t datatype --------------------- */ - -void -glthread_recursive_lock_init_func (gl_recursive_lock_t *lock) -{ - lock->owner = 0; - lock->depth = 0; - InitializeCriticalSection (&lock->lock); - lock->guard.done = 1; -} - -int -glthread_recursive_lock_lock_func (gl_recursive_lock_t *lock) -{ - if (!lock->guard.done) - { - if (InterlockedIncrement (&lock->guard.started) == 0) - /* This thread is the first one to need this lock. Initialize it. */ - glthread_recursive_lock_init (lock); - else - { - /* Don't let lock->guard.started grow and wrap around. */ - InterlockedDecrement (&lock->guard.started); - /* Yield the CPU while waiting for another thread to finish - initializing this lock. */ - while (!lock->guard.done) - Sleep (0); - } - } - { - DWORD self = GetCurrentThreadId (); - if (lock->owner != self) - { - EnterCriticalSection (&lock->lock); - lock->owner = self; - } - if (++(lock->depth) == 0) /* wraparound? */ - { - lock->depth--; - return EAGAIN; - } - } - return 0; -} - -int -glthread_recursive_lock_unlock_func (gl_recursive_lock_t *lock) -{ - if (lock->owner != GetCurrentThreadId ()) - return EPERM; - if (lock->depth == 0) - return EINVAL; - if (--(lock->depth) == 0) - { - lock->owner = 0; - LeaveCriticalSection (&lock->lock); - } - return 0; -} - -int -glthread_recursive_lock_destroy_func (gl_recursive_lock_t *lock) -{ - if (lock->owner != 0) - return EBUSY; - DeleteCriticalSection (&lock->lock); - lock->guard.done = 0; - return 0; -} - #endif /* ========================================================================= */ diff --git a/lib/glthread/lock.h b/lib/glthread/lock.h index e2a49dc..fb1ebc6 100644 --- a/lib/glthread/lock.h +++ b/lib/glthread/lock.h @@ -692,6 +692,7 @@ extern int glthread_once_singlethreaded (gl_once_t *once_control); # include "windows-spinlock.h" # include "windows-mutex.h" +# include "windows-recmutex.h" # include "windows-once.h" # ifdef __cplusplus @@ -774,36 +775,21 @@ extern int glthread_rwlock_destroy_func (gl_rwlock_t *lock); /* --------------------- gl_recursive_lock_t datatype --------------------- */ -/* The native Windows documentation says that CRITICAL_SECTION already - implements a recursive lock. But we need not rely on it: It's easy to - implement a recursive lock without this assumption. */ - -typedef struct - { - glwthread_spinlock_t guard; /* protects the initialization */ - DWORD owner; - unsigned long depth; - CRITICAL_SECTION lock; - } - gl_recursive_lock_t; +typedef glwthread_recmutex_t gl_recursive_lock_t; # define gl_recursive_lock_define(STORAGECLASS, NAME) \ STORAGECLASS gl_recursive_lock_t NAME; # define gl_recursive_lock_define_initialized(STORAGECLASS, NAME) \ STORAGECLASS gl_recursive_lock_t NAME = gl_recursive_lock_initializer; # define gl_recursive_lock_initializer \ - { GLWTHREAD_SPINLOCK_INIT, 0, 0 } + GLWTHREAD_RECMUTEX_INIT # define glthread_recursive_lock_init(LOCK) \ - (glthread_recursive_lock_init_func (LOCK), 0) + (glwthread_recmutex_init (LOCK), 0) # define glthread_recursive_lock_lock(LOCK) \ - glthread_recursive_lock_lock_func (LOCK) + glwthread_recmutex_lock (LOCK) # define glthread_recursive_lock_unlock(LOCK) \ - glthread_recursive_lock_unlock_func (LOCK) + glwthread_recmutex_unlock (LOCK) # define glthread_recursive_lock_destroy(LOCK) \ - glthread_recursive_lock_destroy_func (LOCK) -extern void glthread_recursive_lock_init_func (gl_recursive_lock_t *lock); -extern int glthread_recursive_lock_lock_func (gl_recursive_lock_t *lock); -extern int glthread_recursive_lock_unlock_func (gl_recursive_lock_t *lock); -extern int glthread_recursive_lock_destroy_func (gl_recursive_lock_t *lock); + glwthread_recmutex_destroy (LOCK) /* -------------------------- gl_once_t datatype -------------------------- */ diff --git a/lib/windows-recmutex.c b/lib/windows-recmutex.c new file mode 100644 index 0000000..9629bf4 --- /dev/null +++ b/lib/windows-recmutex.c @@ -0,0 +1,127 @@ +/* Plain recursive mutexes (native Windows implementation). + Copyright (C) 2005-2019 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, see