/* Condition variables for multithreading.
- Copyright (C) 2005-2008 Free Software Foundation, Inc.
+ Copyright (C) 2005-2011 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
#include <errno.h>
#include <stdbool.h>
+#include <stdlib.h>
+#include <time.h>
#include "glthread/lock.h"
/* Use the POSIX threads library. */
# include <pthread.h>
-# include <stdlib.h>
# ifdef __cplusplus
extern "C" {
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) \
# define glthread_cond_destroy(COND) \
(pthread_in_use () ? pthread_cond_destroy (COND) : 0)
+# ifdef __cplusplus
+}
+# endif
+
#endif
/* ========================================================================= */
/* Use the GNU Pth threads library. */
# include <pth.h>
-# include <stdlib.h>
# ifdef __cplusplus
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) \
# define glthread_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
/* ========================================================================= */
# include <thread.h>
# include <synch.h>
-# include <stdlib.h>
# ifdef __cplusplus
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) \
# 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_WIN32_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
+}
+# endif
#endif
/* Macros with built-in error handling. */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#define gl_cond_init(COND) \
do \
{ \
} \
while (0)
+#ifdef __cplusplus
+}
+#endif
+
#endif /* _GLTHREAD_COND_H */