summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruno Haible <bruno@clisp.org>2019-06-20 04:04:45 +0200
committerBruno Haible <bruno@clisp.org>2019-06-20 04:07:03 +0200
commit6c3d118e8303b1f2cfdf17749d39392f1340077d (patch)
treec4c31e84311c7dc5160a5aff6b9dca7b7b95278c
parent7078fef393b8d06c522c690c1fe7017596b12734 (diff)
downloadgnulib-6c3d118e8303b1f2cfdf17749d39392f1340077d.tar.gz
gnulib-6c3d118e8303b1f2cfdf17749d39392f1340077d.tar.bz2
windows-once: New module.
* lib/windows-once.h: New file, extracted from lib/glthread/lock.h. * lib/windows-once.c: New file, extracted from lib/glthread/lock.c. * lib/glthread/lock.h: Include windows-once.h. (gl_once_t): Define using glwthread_once_t. (gl_once_define): Define using GLWTHREAD_ONCE_INIT. (glthread_once): Define using glwthread_once. (glthread_once_func): Remove declaration. * lib/glthread/lock.c (glthread_once_func): Remove function. * modules/windows-once: New file. * modules/lock (Depends-on): Add windows-once.
-rw-r--r--ChangeLog14
-rw-r--r--lib/glthread/lock.c39
-rw-r--r--lib/glthread/lock.h15
-rw-r--r--lib/windows-once.c62
-rw-r--r--lib/windows-once.h47
-rw-r--r--modules/lock1
-rw-r--r--modules/windows-once27
7 files changed, 156 insertions, 49 deletions
diff --git a/ChangeLog b/ChangeLog
index ba91fdac96..06474ea4a9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,19 @@
2019-06-20 Bruno Haible <bruno@clisp.org>
+ windows-once: New module.
+ * lib/windows-once.h: New file, extracted from lib/glthread/lock.h.
+ * lib/windows-once.c: New file, extracted from lib/glthread/lock.c.
+ * lib/glthread/lock.h: Include windows-once.h.
+ (gl_once_t): Define using glwthread_once_t.
+ (gl_once_define): Define using GLWTHREAD_ONCE_INIT.
+ (glthread_once): Define using glwthread_once.
+ (glthread_once_func): Remove declaration.
+ * lib/glthread/lock.c (glthread_once_func): Remove function.
+ * modules/windows-once: New file.
+ * modules/lock (Depends-on): Add windows-once.
+
+2019-06-20 Bruno Haible <bruno@clisp.org>
+
lock, cond: Avoid possible counter wraparound on Windows.
* lib/glthread/lock.c (glthread_lock_lock_func): Leave the 'started'
field of the guard unchanged if it was already positive.
diff --git a/lib/glthread/lock.c b/lib/glthread/lock.c
index 4774573675..587d1e7a29 100644
--- a/lib/glthread/lock.c
+++ b/lib/glthread/lock.c
@@ -1193,45 +1193,6 @@ glthread_recursive_lock_destroy_func (gl_recursive_lock_t *lock)
return 0;
}
-/* -------------------------- gl_once_t datatype -------------------------- */
-
-void
-glthread_once_func (gl_once_t *once_control, void (*initfunction) (void))
-{
- if (once_control->inited <= 0)
- {
- if (InterlockedIncrement (&once_control->started) == 0)
- {
- /* This thread is the first one to come to this once_control. */
- InitializeCriticalSection (&once_control->lock);
- EnterCriticalSection (&once_control->lock);
- once_control->inited = 0;
- initfunction ();
- once_control->inited = 1;
- LeaveCriticalSection (&once_control->lock);
- }
- else
- {
- /* Don't let once_control->started grow and wrap around. */
- InterlockedDecrement (&once_control->started);
- /* Some other thread has already started the initialization.
- Yield the CPU while waiting for the other thread to finish
- initializing and taking the lock. */
- while (once_control->inited < 0)
- Sleep (0);
- if (once_control->inited <= 0)
- {
- /* Take the lock. This blocks until the other thread has
- finished calling the initfunction. */
- EnterCriticalSection (&once_control->lock);
- LeaveCriticalSection (&once_control->lock);
- if (!(once_control->inited > 0))
- abort ();
- }
- }
- }
-}
-
#endif
/* ========================================================================= */
diff --git a/lib/glthread/lock.h b/lib/glthread/lock.h
index cc6fb5e60d..93e2e48241 100644
--- a/lib/glthread/lock.h
+++ b/lib/glthread/lock.h
@@ -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-once.h"
+
# ifdef __cplusplus
extern "C" {
# endif
@@ -814,18 +816,11 @@ extern int glthread_recursive_lock_destroy_func (gl_recursive_lock_t *lock);
/* -------------------------- gl_once_t datatype -------------------------- */
-typedef struct
- {
- volatile int inited;
- volatile long started;
- CRITICAL_SECTION lock;
- }
- gl_once_t;
+typedef glwthread_once_t gl_once_t;
# define gl_once_define(STORAGECLASS, NAME) \
- STORAGECLASS gl_once_t NAME = { -1, -1 };
+ STORAGECLASS gl_once_t NAME = GLWTHREAD_ONCE_INIT;
# define glthread_once(ONCE_CONTROL, INITFUNCTION) \
- (glthread_once_func (ONCE_CONTROL, INITFUNCTION), 0)
-extern void glthread_once_func (gl_once_t *once_control, void (*initfunction) (void));
+ (glwthread_once (ONCE_CONTROL, INITFUNCTION), 0)
# ifdef __cplusplus
}
diff --git a/lib/windows-once.c b/lib/windows-once.c
new file mode 100644
index 0000000000..4a18922aaf
--- /dev/null
+++ b/lib/windows-once.c
@@ -0,0 +1,62 @@
+/* Once-only control (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-once.h"
+
+#include <stdlib.h>
+
+void
+glwthread_once (glwthread_once_t *once_control, void (*initfunction) (void))
+{
+ if (once_control->inited <= 0)
+ {
+ if (InterlockedIncrement (&once_control->started) == 0)
+ {
+ /* This thread is the first one to come to this once_control. */
+ InitializeCriticalSection (&once_control->lock);
+ EnterCriticalSection (&once_control->lock);
+ once_control->inited = 0;
+ initfunction ();
+ once_control->inited = 1;
+ LeaveCriticalSection (&once_control->lock);
+ }
+ else
+ {
+ /* Don't let once_control->started grow and wrap around. */
+ InterlockedDecrement (&once_control->started);
+ /* Some other thread has already started the initialization.
+ Yield the CPU while waiting for the other thread to finish
+ initializing and taking the lock. */
+ while (once_control->inited < 0)
+ Sleep (0);
+ if (once_control->inited <= 0)
+ {
+ /* Take the lock. This blocks until the other thread has
+ finished calling the initfunction. */
+ EnterCriticalSection (&once_control->lock);
+ LeaveCriticalSection (&once_control->lock);
+ if (!(once_control->inited > 0))
+ abort ();
+ }
+ }
+ }
+}
diff --git a/lib/windows-once.h b/lib/windows-once.h
new file mode 100644
index 0000000000..8b56a392d9
--- /dev/null
+++ b/lib/windows-once.h
@@ -0,0 +1,47 @@
+/* Once-only control (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_ONCE_H
+#define _WINDOWS_ONCE_H
+
+#define WIN32_LEAN_AND_MEAN /* avoid including junk */
+#include <windows.h>
+
+typedef struct
+ {
+ volatile int inited;
+ volatile LONG started;
+ CRITICAL_SECTION lock;
+ }
+ glwthread_once_t;
+
+#define GLWTHREAD_ONCE_INIT { -1, -1 }
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern void glwthread_once (glwthread_once_t *once_control,
+ void (*initfunction) (void));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _WINDOWS_ONCE_H */
diff --git a/modules/lock b/modules/lock
index dafeeeba3c..fca83413ad 100644
--- a/modules/lock
+++ b/modules/lock
@@ -10,6 +10,7 @@ m4/pthread_rwlock_rdlock.m4
Depends-on:
extensions
threadlib
+windows-once [test $gl_threads_api = windows]
configure.ac:
gl_LOCK
diff --git a/modules/windows-once b/modules/windows-once
new file mode 100644
index 0000000000..34d5b1e3bd
--- /dev/null
+++ b/modules/windows-once
@@ -0,0 +1,27 @@
+Description:
+Once-only control (native Windows implementation).
+
+Files:
+lib/windows-once.h
+lib/windows-once.c
+
+Depends-on:
+
+configure.ac:
+AC_REQUIRE([AC_CANONICAL_HOST])
+case "$host_os" in
+ mingw*)
+ AC_LIBOBJ([windows-once])
+ ;;
+esac
+
+Makefile.am:
+
+Include:
+"windows-once.h"
+
+License:
+LGPLv2+
+
+Maintainer:
+all

Return to:

Send suggestions and report system problems to the System administrator.