]> git.ipfire.org Git - thirdparty/gnulib.git/commitdiff
windows-mutex: New module.
authorBruno Haible <bruno@clisp.org>
Thu, 20 Jun 2019 02:08:16 +0000 (04:08 +0200)
committerBruno Haible <bruno@clisp.org>
Thu, 20 Jun 2019 02:08:59 +0000 (04:08 +0200)
* lib/windows-mutex.h: New file, extracted from lib/glthread/lock.h.
* lib/windows-mutex.c: New file, extracted from lib/glthread/lock.c.
* lib/windows-spinlock.h: New file, extracted from lib/glthread/lock.h.
* lib/glthread/lock.h: Include windows-spinlock.h, windows-mutex.h.
(gl_spinlock_t): Remove type.
(gl_lock_t): Define using glwthread_mutex_t.
(gl_lock_initializer): Define using GLWTHREAD_MUTEX_INIT.
(glthread_lock_init): Define using glwthread_mutex_init.
(glthread_lock_lock): Define using glwthread_mutex_lock.
(glthread_lock_unlock): Define using glwthread_mutex_unlock.
(glthread_lock_destroy): Define using glwthread_mutex_destroy.
(glthread_lock_init_func, glthread_lock_lock_func,
glthread_lock_unlock_func, glthread_lock_destroy_func): Remove
declarations.
Use glwthread_spinlock_t instead of gl_spinlock_t.
(gl_rwlock_initializer, gl_recursive_lock_initializer): Define using
GLWTHREAD_SPINLOCK_INIT.
* lib/glthread/lock.c (glthread_lock_init_func, glthread_lock_lock_func,
glthread_lock_unlock_func, glthread_lock_destroy_func): Remove
functions.
* lib/glthread/cond.h: Use glwthread_spinlock_t instead of
gl_spinlock_t.
* modules/windows-mutex: New file.
* modules/lock (Depends-on): Add windows-mutex.

ChangeLog
lib/glthread/cond.h
lib/glthread/lock.c
lib/glthread/lock.h
lib/windows-mutex.c [new file with mode: 0644]
lib/windows-mutex.h [new file with mode: 0644]
lib/windows-spinlock.h [new file with mode: 0644]
modules/lock
modules/windows-mutex [new file with mode: 0644]

index 06474ea4a906fcb79e496581cd11188352dfca62..a168b238bca8b3fb7bd80d91c052dfdfdd76b5d8 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,31 @@
+2019-06-20  Bruno Haible  <bruno@clisp.org>
+
+       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.
+       * lib/windows-spinlock.h: New file, extracted from lib/glthread/lock.h.
+       * lib/glthread/lock.h: Include windows-spinlock.h, windows-mutex.h.
+       (gl_spinlock_t): Remove type.
+       (gl_lock_t): Define using glwthread_mutex_t.
+       (gl_lock_initializer): Define using GLWTHREAD_MUTEX_INIT.
+       (glthread_lock_init): Define using glwthread_mutex_init.
+       (glthread_lock_lock): Define using glwthread_mutex_lock.
+       (glthread_lock_unlock): Define using glwthread_mutex_unlock.
+       (glthread_lock_destroy): Define using glwthread_mutex_destroy.
+       (glthread_lock_init_func, glthread_lock_lock_func,
+       glthread_lock_unlock_func, glthread_lock_destroy_func): Remove
+       declarations.
+       Use glwthread_spinlock_t instead of gl_spinlock_t.
+       (gl_rwlock_initializer, gl_recursive_lock_initializer): Define using
+       GLWTHREAD_SPINLOCK_INIT.
+       * lib/glthread/lock.c (glthread_lock_init_func, glthread_lock_lock_func,
+       glthread_lock_unlock_func, glthread_lock_destroy_func): Remove
+       functions.
+       * lib/glthread/cond.h: Use glwthread_spinlock_t instead of
+       gl_spinlock_t.
+       * modules/windows-mutex: New file.
+       * modules/lock (Depends-on): Add windows-mutex.
+
 2019-06-20  Bruno Haible  <bruno@clisp.org>
 
        windows-once: New module.
index 6540f1df8ed2bd2939dc8f1e1a6b199299c2413a..f252c329cc7d1d346f1339a1b12895421d4437e1 100644 (file)
@@ -311,7 +311,7 @@ typedef struct
         gl_linked_waitqueue_t;
 typedef struct
         {
-          gl_spinlock_t guard; /* protects the initialization */
+          glwthread_spinlock_t guard; /* protects the initialization */
           CRITICAL_SECTION lock; /* protects the remaining fields */
           gl_linked_waitqueue_t waiters; /* waiting threads */
         }
index 587d1e7a2969f59c993b1d58a63cf373eadfb636..e17f524ca15241ffba5b7ea85445930e944b2893 100644 (file)
@@ -793,56 +793,6 @@ glthread_once_singlethreaded (gl_once_t *once_control)
 
 #if USE_WINDOWS_THREADS
 
-/* -------------------------- gl_lock_t datatype -------------------------- */
-
-void
-glthread_lock_init_func (gl_lock_t *lock)
-{
-  InitializeCriticalSection (&lock->lock);
-  lock->guard.done = 1;
-}
-
-int
-glthread_lock_lock_func (gl_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_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);
-        }
-    }
-  EnterCriticalSection (&lock->lock);
-  return 0;
-}
-
-int
-glthread_lock_unlock_func (gl_lock_t *lock)
-{
-  if (!lock->guard.done)
-    return EINVAL;
-  LeaveCriticalSection (&lock->lock);
-  return 0;
-}
-
-int
-glthread_lock_destroy_func (gl_lock_t *lock)
-{
-  if (!lock->guard.done)
-    return EINVAL;
-  DeleteCriticalSection (&lock->lock);
-  lock->guard.done = 0;
-  return 0;
-}
-
 /* ------------------------- gl_rwlock_t datatype ------------------------- */
 
 /* In this file, the waitqueues are implemented as circular arrays.  */
index 93e2e48241739ae3d69867d302f950f047a2ac8d..e2a49dcec77e7b4dc82724620ee05dd305d1377b 100644 (file)
@@ -690,6 +690,8 @@ extern int glthread_once_singlethreaded (gl_once_t *once_control);
 # define WIN32_LEAN_AND_MEAN  /* avoid including junk */
 # include <windows.h>
 
+# include "windows-spinlock.h"
+# include "windows-mutex.h"
 # include "windows-once.h"
 
 # ifdef __cplusplus
@@ -707,34 +709,23 @@ extern "C" {
 /* There is no way to statically initialize a CRITICAL_SECTION.  It needs
    to be done lazily, once only.  For this we need spinlocks.  */
 
-typedef struct { volatile int done; volatile long started; } gl_spinlock_t;
-
 /* -------------------------- gl_lock_t datatype -------------------------- */
 
-typedef struct
-        {
-          gl_spinlock_t guard; /* protects the initialization */
-          CRITICAL_SECTION lock;
-        }
-        gl_lock_t;
+typedef glwthread_mutex_t gl_lock_t;
 # define gl_lock_define(STORAGECLASS, NAME) \
     STORAGECLASS gl_lock_t NAME;
 # define gl_lock_define_initialized(STORAGECLASS, NAME) \
     STORAGECLASS gl_lock_t NAME = gl_lock_initializer;
 # define gl_lock_initializer \
-    { { 0, -1 } }
+    GLWTHREAD_MUTEX_INIT
 # define glthread_lock_init(LOCK) \
-    (glthread_lock_init_func (LOCK), 0)
+    (glwthread_mutex_init (LOCK), 0)
 # define glthread_lock_lock(LOCK) \
-    glthread_lock_lock_func (LOCK)
+    glwthread_mutex_lock (LOCK)
 # define glthread_lock_unlock(LOCK) \
-    glthread_lock_unlock_func (LOCK)
+    glwthread_mutex_unlock (LOCK)
 # define glthread_lock_destroy(LOCK) \
-    glthread_lock_destroy_func (LOCK)
-extern void glthread_lock_init_func (gl_lock_t *lock);
-extern int glthread_lock_lock_func (gl_lock_t *lock);
-extern int glthread_lock_unlock_func (gl_lock_t *lock);
-extern int glthread_lock_destroy_func (gl_lock_t *lock);
+    glwthread_mutex_destroy (LOCK)
 
 /* ------------------------- gl_rwlock_t datatype ------------------------- */
 
@@ -752,7 +743,7 @@ typedef struct
         gl_carray_waitqueue_t;
 typedef struct
         {
-          gl_spinlock_t guard; /* protects the initialization */
+          glwthread_spinlock_t guard; /* protects the initialization */
           CRITICAL_SECTION lock; /* protects the remaining fields */
           gl_carray_waitqueue_t waiting_readers; /* waiting readers */
           gl_carray_waitqueue_t waiting_writers; /* waiting writers */
@@ -764,7 +755,7 @@ typedef struct
 # define gl_rwlock_define_initialized(STORAGECLASS, NAME) \
     STORAGECLASS gl_rwlock_t NAME = gl_rwlock_initializer;
 # define gl_rwlock_initializer \
-    { { 0, -1 } }
+    { GLWTHREAD_SPINLOCK_INIT }
 # define glthread_rwlock_init(LOCK) \
     (glthread_rwlock_init_func (LOCK), 0)
 # define glthread_rwlock_rdlock(LOCK) \
@@ -789,7 +780,7 @@ extern int glthread_rwlock_destroy_func (gl_rwlock_t *lock);
 
 typedef struct
         {
-          gl_spinlock_t guard; /* protects the initialization */
+          glwthread_spinlock_t guard; /* protects the initialization */
           DWORD owner;
           unsigned long depth;
           CRITICAL_SECTION lock;
@@ -800,7 +791,7 @@ typedef struct
 # define gl_recursive_lock_define_initialized(STORAGECLASS, NAME) \
     STORAGECLASS gl_recursive_lock_t NAME = gl_recursive_lock_initializer;
 # define gl_recursive_lock_initializer \
-    { { 0, -1 }, 0, 0 }
+    { GLWTHREAD_SPINLOCK_INIT, 0, 0 }
 # define glthread_recursive_lock_init(LOCK) \
     (glthread_recursive_lock_init_func (LOCK), 0)
 # define glthread_recursive_lock_lock(LOCK) \
diff --git a/lib/windows-mutex.c b/lib/windows-mutex.c
new file mode 100644 (file)
index 0000000..e2c94b8
--- /dev/null
@@ -0,0 +1,95 @@
+/* Plain 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 <https://www.gnu.org/licenses/>.  */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2005.
+   Based on GCC's gthr-win32.h.  */
+
+#include <config.h>
+
+/* Specification.  */
+#include "windows-mutex.h"
+
+#include <errno.h>
+
+void
+glwthread_mutex_init (glwthread_mutex_t *mutex)
+{
+  InitializeCriticalSection (&mutex->lock);
+  mutex->guard.done = 1;
+}
+
+int
+glwthread_mutex_lock (glwthread_mutex_t *mutex)
+{
+  if (!mutex->guard.done)
+    {
+      if (InterlockedIncrement (&mutex->guard.started) == 0)
+        /* This thread is the first one to need this mutex.  Initialize it.  */
+        glwthread_mutex_init (mutex);
+      else
+        {
+          /* Don't let mutex->guard.started grow and wrap around.  */
+          InterlockedDecrement (&mutex->guard.started);
+          /* Yield the CPU while waiting for another thread to finish
+             initializing this mutex.  */
+          while (!mutex->guard.done)
+            Sleep (0);
+        }
+    }
+  EnterCriticalSection (&mutex->lock);
+  return 0;
+}
+
+int
+glwthread_mutex_trylock (glwthread_mutex_t *mutex)
+{
+  if (!mutex->guard.done)
+    {
+      if (InterlockedIncrement (&mutex->guard.started) == 0)
+        /* This thread is the first one to need this mutex.  Initialize it.  */
+        glwthread_mutex_init (mutex);
+      else
+        {
+          /* Don't let mutex->guard.started grow and wrap around.  */
+          InterlockedDecrement (&mutex->guard.started);
+          /* Let another thread finish initializing this mutex, and let it also
+             lock this mutex.  */
+          return EBUSY;
+        }
+    }
+  if (!TryEnterCriticalSection (&mutex->lock))
+    return EBUSY;
+  return 0;
+}
+
+int
+glwthread_mutex_unlock (glwthread_mutex_t *mutex)
+{
+  if (!mutex->guard.done)
+    return EINVAL;
+  LeaveCriticalSection (&mutex->lock);
+  return 0;
+}
+
+int
+glwthread_mutex_destroy (glwthread_mutex_t *mutex)
+{
+  if (!mutex->guard.done)
+    return EINVAL;
+  DeleteCriticalSection (&mutex->lock);
+  mutex->guard.done = 0;
+  return 0;
+}
diff --git a/lib/windows-mutex.h b/lib/windows-mutex.h
new file mode 100644 (file)
index 0000000..edc738e
--- /dev/null
@@ -0,0 +1,51 @@
+/* Plain 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 <https://www.gnu.org/licenses/>.  */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2005.
+   Based on GCC's gthr-win32.h.  */
+
+#ifndef _WINDOWS_MUTEX_H
+#define _WINDOWS_MUTEX_H
+
+#define WIN32_LEAN_AND_MEAN  /* avoid including junk */
+#include <windows.h>
+
+#include "windows-spinlock.h"
+
+typedef struct
+        {
+          glwthread_spinlock_t guard; /* protects the initialization */
+          CRITICAL_SECTION lock;
+        }
+        glwthread_mutex_t;
+
+#define GLWTHREAD_MUTEX_INIT { GLWTHREAD_SPINLOCK_INIT }
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern void glwthread_mutex_init (glwthread_mutex_t *mutex);
+extern int glwthread_mutex_lock (glwthread_mutex_t *mutex);
+extern int glwthread_mutex_trylock (glwthread_mutex_t *mutex);
+extern int glwthread_mutex_unlock (glwthread_mutex_t *mutex);
+extern int glwthread_mutex_destroy (glwthread_mutex_t *mutex);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _WINDOWS_MUTEX_H */
diff --git a/lib/windows-spinlock.h b/lib/windows-spinlock.h
new file mode 100644 (file)
index 0000000..26a4b65
--- /dev/null
@@ -0,0 +1,35 @@
+/* Spinlocks (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 <https://www.gnu.org/licenses/>.  */
+
+/* Written by Bruno Haible <bruno@clisp.org>, 2005.
+   Based on GCC's gthr-win32.h.  */
+
+#ifndef _WINDOWS_SPINLOCK_H
+#define _WINDOWS_SPINLOCK_H
+
+#define WIN32_LEAN_AND_MEAN  /* avoid including junk */
+#include <windows.h>
+
+typedef struct
+        {
+          volatile int done;
+          volatile LONG started;
+        }
+        glwthread_spinlock_t;
+
+#define GLWTHREAD_SPINLOCK_INIT { 0, -1 }
+
+#endif /* _WINDOWS_SPINLOCK_H */
index fca83413add1e8b32d5bf33b9b48adc8413b805d..351e902bc98134e11579e298647249fcd147c103 100644 (file)
@@ -10,6 +10,7 @@ m4/pthread_rwlock_rdlock.m4
 Depends-on:
 extensions
 threadlib
+windows-mutex   [test $gl_threads_api = windows]
 windows-once    [test $gl_threads_api = windows]
 
 configure.ac:
diff --git a/modules/windows-mutex b/modules/windows-mutex
new file mode 100644 (file)
index 0000000..18aabcc
--- /dev/null
@@ -0,0 +1,28 @@
+Description:
+Plain mutexes (native Windows implementation).
+
+Files:
+lib/windows-mutex.h
+lib/windows-mutex.c
+lib/windows-spinlock.h
+
+Depends-on:
+
+configure.ac:
+AC_REQUIRE([AC_CANONICAL_HOST])
+case "$host_os" in
+  mingw*)
+    AC_LIBOBJ([windows-mutex])
+    ;;
+esac
+
+Makefile.am:
+
+Include:
+"windows-mutex.h"
+
+License:
+LGPLv2+
+
+Maintainer:
+all