maint: update copyright
[gnulib.git] / lib / glthread / cond.h
index f71e627..bf709a2 100644 (file)
@@ -1,5 +1,5 @@
 /* Condition variables for multithreading.
-   Copyright (C) 2005-2008 Free Software Foundation, Inc.
+   Copyright (C) 2005-2014 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
@@ -12,8 +12,7 @@
    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, write to the Free Software Foundation,
-   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.  */
+   along with this program; if not, see <http://www.gnu.org/licenses/>.  */
 
 /* Written by Yoann Vandoorselaere <yoann@prelude-ids.org>, 2008.
    Based on Bruno Haible <bruno@clisp.org> lock.h */
 #include <errno.h>
 #include <stdbool.h>
 #include <stdlib.h>
+#include <time.h>
 
 #include "glthread/lock.h"
+#ifndef _GL_INLINE_HEADER_BEGIN
+ #error "Please include config.h first."
+#endif
+
+_GL_INLINE_HEADER_BEGIN
+#ifndef _GLTHREAD_COND_INLINE
+# define _GLTHREAD_COND_INLINE _GL_INLINE
+#endif
 
 /* ========================================================================= */
 
@@ -122,9 +130,9 @@ extern int glthread_in_use (void);
 
 typedef pthread_cond_t gl_cond_t;
 # define gl_cond_define(STORAGECLASS, NAME) \
-    STORAGECLASS pthread_cond_t NAME;
+    STORAGECLASS gl_cond_t NAME;
 # define gl_cond_define_initialized(STORAGECLASS, NAME) \
-    STORAGECLASS pthread_cond_t NAME = gl_cond_initializer;
+    STORAGECLASS gl_cond_t NAME = gl_cond_initializer;
 # define gl_cond_initializer \
     PTHREAD_COND_INITIALIZER
 # define glthread_cond_init(COND) \
@@ -181,9 +189,9 @@ extern "C" {
 
 typedef pth_cond_t gl_cond_t;
 # define gl_cond_define(STORAGECLASS, NAME) \
-    STORAGECLASS pth_cond_t NAME;
+    STORAGECLASS gl_cond_t NAME;
 # define gl_cond_define_initialized(STORAGECLASS, NAME) \
-    STORAGECLASS pth_cond_t NAME = gl_cond_initializer;
+    STORAGECLASS gl_cond_t NAME = gl_cond_initializer;
 # define gl_cond_initializer \
     PTH_COND_INIT
 # define glthread_cond_init(COND) \
@@ -239,13 +247,11 @@ extern "C" {
 
 /* -------------------------- gl_cond_t datatype -------------------------- */
 
-#define ETIMEDOUT ETIME
-
-typedef pthread_cond_t gl_cond_t;
+typedef cond_t gl_cond_t;
 # define gl_cond_define(STORAGECLASS, NAME) \
-    STORAGECLASS cond_t NAME;
+    STORAGECLASS gl_cond_t NAME;
 # define gl_cond_define_initialized(STORAGECLASS, NAME) \
-    STORAGECLASS cond_t NAME = gl_cond_initializer;
+    STORAGECLASS gl_cond_t NAME = gl_cond_initializer;
 # define gl_cond_initializer \
     DEFAULTCV
 # define glthread_cond_init(COND) \
@@ -253,13 +259,75 @@ typedef pthread_cond_t gl_cond_t;
 # define glthread_cond_wait(COND, LOCK) \
     (pthread_in_use () ? cond_wait (COND, LOCK) : 0)
 # define glthread_cond_timedwait(COND, LOCK, ABSTIME) \
-    (pthread_in_use () ? cond_timedwait (COND, LOCK, ABSTIME) : 0)
+    (pthread_in_use () ? glthread_cond_timedwait_multithreaded (COND, LOCK, ABSTIME) : 0)
 # define glthread_cond_signal(COND) \
     (pthread_in_use () ? cond_signal (COND) : 0)
 # define glthread_cond_broadcast(COND) \
     (pthread_in_use () ? cond_broadcast (COND) : 0)
 # define glthread_cond_destroy(COND) \
     (pthread_in_use () ? cond_destroy (COND) : 0)
+extern int glthread_cond_timedwait_multithreaded (gl_cond_t *cond, gl_lock_t *lock, struct timespec *abstime);
+
+# ifdef __cplusplus
+}
+# endif
+
+#endif
+
+/* ========================================================================= */
+
+#if USE_WINDOWS_THREADS
+
+# define WIN32_LEAN_AND_MEAN  /* avoid including junk */
+# include <windows.h>
+
+# ifdef __cplusplus
+extern "C" {
+# endif
+
+/* -------------------------- gl_cond_t datatype -------------------------- */
+
+struct gl_waitqueue_link
+{
+  struct gl_waitqueue_link *wql_next;
+  struct gl_waitqueue_link *wql_prev;
+};
+typedef struct
+        {
+          struct gl_waitqueue_link wq_list; /* circular list of waiting threads */
+        }
+        gl_linked_waitqueue_t;
+typedef struct
+        {
+          gl_spinlock_t guard; /* protects the initialization */
+          CRITICAL_SECTION lock; /* protects the remaining fields */
+          gl_linked_waitqueue_t waiters; /* waiting threads */
+        }
+        gl_cond_t;
+# define gl_cond_define(STORAGECLASS, NAME) \
+    STORAGECLASS gl_cond_t NAME;
+# define gl_cond_define_initialized(STORAGECLASS, NAME) \
+    STORAGECLASS gl_cond_t NAME = gl_cond_initializer;
+# define gl_cond_initializer \
+    { { 0, -1 } }
+# define glthread_cond_init(COND) \
+    glthread_cond_init_func (COND)
+# define glthread_cond_wait(COND, LOCK) \
+    glthread_cond_wait_func (COND, LOCK)
+# define glthread_cond_timedwait(COND, LOCK, ABSTIME) \
+    glthread_cond_timedwait_func (COND, LOCK, ABSTIME)
+# define glthread_cond_signal(COND) \
+    glthread_cond_signal_func (COND)
+# define glthread_cond_broadcast(COND) \
+    glthread_cond_broadcast_func (COND)
+# define glthread_cond_destroy(COND) \
+    glthread_cond_destroy_func (COND)
+extern int glthread_cond_init_func (gl_cond_t *cond);
+extern int glthread_cond_wait_func (gl_cond_t *cond, gl_lock_t *lock);
+extern int glthread_cond_timedwait_func (gl_cond_t *cond, gl_lock_t *lock, struct timespec *abstime);
+extern int glthread_cond_signal_func (gl_cond_t *cond);
+extern int glthread_cond_broadcast_func (gl_cond_t *cond);
+extern int glthread_cond_destroy_func (gl_cond_t *cond);
 
 # ifdef __cplusplus
 }
@@ -269,7 +337,7 @@ typedef pthread_cond_t gl_cond_t;
 
 /* ========================================================================= */
 
-#if !(USE_POSIX_THREADS || USE_PTH_THREADS || USE_SOLARIS_THREADS || USE_WIN32_THREADS)
+#if !(USE_POSIX_THREADS || USE_PTH_THREADS || USE_SOLARIS_THREADS || USE_WINDOWS_THREADS)
 
 /* Provide dummy implementation if threads are not supported.  */
 
@@ -309,7 +377,7 @@ extern "C" {
    while (0)
 #define gl_cond_timedwait(COND, LOCK, ABSTIME) \
   gl_cond_timedwait_func (&COND, &LOCK, ABSTIME)
-static inline bool
+_GLTHREAD_COND_INLINE bool
 gl_cond_timedwait_func (gl_cond_t *cond, gl_lock_t *lock, struct timespec *abstime)
 {
   int err = glthread_cond_timedwait (cond, lock, abstime);
@@ -345,4 +413,6 @@ gl_cond_timedwait_func (gl_cond_t *cond, gl_lock_t *lock, struct timespec *absti
 }
 #endif
 
+_GL_INLINE_HEADER_END
+
 #endif /* _GLTHREAD_COND_H */