X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Flock.h;h=be99139dce7a9e787d5c05564cbe0e38fa950928;hb=a8df888bfdbd98882a6909821db496b1ef9f5b36;hp=9ca33debcd252ac698c5b4c2a2b977df31b1dfbb;hpb=76c867feaa6cca1cd900a33712f429474bcbd982;p=gnulib.git diff --git a/lib/lock.h b/lib/lock.h index 9ca33debc..be99139dc 100644 --- a/lib/lock.h +++ b/lib/lock.h @@ -51,9 +51,17 @@ Taking the lock: gl_recursive_lock_lock (name); Releasing the lock: gl_recursive_lock_unlock (name); De-initialization: gl_recursive_lock_destroy (name); + + Once-only execution: + Type: gl_once_t + Initializer: gl_once_define(extern, name) + Execution: gl_once (name, initfunction); */ +#ifndef _LOCK_H +#define _LOCK_H + /* ========================================================================= */ #if USE_POSIX_THREADS @@ -63,6 +71,15 @@ # include # include +# if PTHREAD_IN_USE_DETECTION_HARD + +/* The pthread_in_use() detection needs to be done at runtime. */ +# define pthread_in_use() \ + glthread_in_use () +extern int glthread_in_use (void); + +# endif + # if USE_POSIX_THREADS_WEAK /* Use weak references to the POSIX threads library. */ @@ -91,6 +108,7 @@ # pragma weak pthread_rwlock_wrlock # pragma weak pthread_rwlock_unlock # pragma weak pthread_rwlock_destroy +# pragma weak pthread_once # pragma weak pthread_cond_init # pragma weak pthread_cond_wait # pragma weak pthread_cond_signal @@ -103,12 +121,16 @@ # pragma weak pthread_self # endif -# pragma weak pthread_cancel -# define pthread_in_use() (pthread_cancel != NULL) +# if !PTHREAD_IN_USE_DETECTION_HARD +# pragma weak pthread_cancel +# define pthread_in_use() (pthread_cancel != NULL) +# endif # else -# define pthread_in_use() 1 +# if !PTHREAD_IN_USE_DETECTION_HARD +# define pthread_in_use() 1 +# endif # endif @@ -118,7 +140,9 @@ typedef pthread_mutex_t gl_lock_t; # define gl_lock_define(STORAGECLASS, NAME) \ STORAGECLASS pthread_mutex_t NAME; # define gl_lock_define_initialized(STORAGECLASS, NAME) \ - STORAGECLASS pthread_mutex_t NAME = PTHREAD_MUTEX_INITIALIZER; + STORAGECLASS pthread_mutex_t NAME = gl_lock_initializer; +# define gl_lock_initializer \ + PTHREAD_MUTEX_INITIALIZER # define gl_lock_init(NAME) \ if (pthread_in_use () && pthread_mutex_init (&NAME, NULL) != 0) abort () # define gl_lock_lock(NAME) \ @@ -138,7 +162,9 @@ typedef pthread_rwlock_t gl_rwlock_t; # define gl_rwlock_define(STORAGECLASS, NAME) \ STORAGECLASS pthread_rwlock_t NAME; # define gl_rwlock_define_initialized(STORAGECLASS, NAME) \ - STORAGECLASS pthread_rwlock_t NAME = PTHREAD_RWLOCK_INITIALIZER; + STORAGECLASS pthread_rwlock_t NAME = gl_rwlock_initializer; +# define gl_rwlock_initializer \ + PTHREAD_RWLOCK_INITIALIZER # define gl_rwlock_init(NAME) \ if (pthread_in_use () && pthread_rwlock_init (&NAME, NULL) != 0) abort () # define gl_rwlock_rdlock(NAME) \ @@ -162,7 +188,9 @@ typedef struct # define gl_rwlock_define(STORAGECLASS, NAME) \ STORAGECLASS gl_rwlock_t NAME; # define gl_rwlock_define_initialized(STORAGECLASS, NAME) \ - STORAGECLASS gl_rwlock_t NAME = { 0, PTHREAD_MUTEX_INITIALIZER }; + STORAGECLASS gl_rwlock_t NAME = gl_rwlock_initializer; +# define gl_rwlock_initializer \ + { 0, PTHREAD_MUTEX_INITIALIZER } # define gl_rwlock_init(NAME) \ if (pthread_in_use ()) glthread_rwlock_init (&NAME) # define gl_rwlock_rdlock(NAME) \ @@ -195,8 +223,9 @@ typedef struct # define gl_rwlock_define(STORAGECLASS, NAME) \ STORAGECLASS gl_rwlock_t NAME; # define gl_rwlock_define_initialized(STORAGECLASS, NAME) \ - STORAGECLASS gl_rwlock_t NAME = \ - { PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, PTHREAD_COND_INITIALIZER, 0, 0 }; + STORAGECLASS gl_rwlock_t NAME = gl_rwlock_initializer; +# define gl_rwlock_initializer \ + { PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, PTHREAD_COND_INITIALIZER, 0, 0 } # define gl_rwlock_init(NAME) \ if (pthread_in_use ()) glthread_rwlock_init (&NAME) # define gl_rwlock_rdlock(NAME) \ @@ -224,12 +253,14 @@ extern void glthread_rwlock_destroy (gl_rwlock_t *lock); typedef pthread_mutex_t gl_recursive_lock_t; # define gl_recursive_lock_define(STORAGECLASS, NAME) \ STORAGECLASS pthread_mutex_t NAME; +# define gl_recursive_lock_define_initialized(STORAGECLASS, NAME) \ + STORAGECLASS pthread_mutex_t NAME = gl_recursive_lock_initializer; # ifdef PTHREAD_RECURSIVE_MUTEX_INITIALIZER -# define gl_recursive_lock_define_initialized(STORAGECLASS, NAME) \ - STORAGECLASS pthread_mutex_t NAME = PTHREAD_RECURSIVE_MUTEX_INITIALIZER; +# define gl_recursive_lock_initializer \ + PTHREAD_RECURSIVE_MUTEX_INITIALIZER # else -# define gl_recursive_lock_define_initialized(STORAGECLASS, NAME) \ - STORAGECLASS pthread_mutex_t NAME = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP; +# define gl_recursive_lock_initializer \ + PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP # endif # define gl_recursive_lock_init(NAME) \ if (pthread_in_use () && pthread_mutex_init (&NAME, NULL) != 0) abort () @@ -252,8 +283,9 @@ typedef struct # 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 = \ - { PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, 0 }; + STORAGECLASS gl_recursive_lock_t NAME = gl_recursive_lock_initializer; +# define gl_recursive_lock_initializer \ + { PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, 0 } # define gl_recursive_lock_init(NAME) \ if (pthread_in_use ()) glthread_recursive_lock_init (&NAME) # define gl_recursive_lock_lock(NAME) \ @@ -284,8 +316,9 @@ typedef struct # 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 = \ - { PTHREAD_MUTEX_INITIALIZER, (pthread_t) 0, 0 }; + STORAGECLASS gl_recursive_lock_t NAME = gl_recursive_lock_initializer; +# define gl_recursive_lock_initializer \ + { PTHREAD_MUTEX_INITIALIZER, (pthread_t) 0, 0 } # define gl_recursive_lock_init(NAME) \ if (pthread_in_use ()) glthread_recursive_lock_init (&NAME) # define gl_recursive_lock_lock(NAME) \ @@ -301,6 +334,28 @@ extern void glthread_recursive_lock_destroy (gl_recursive_lock_t *lock); # endif +/* -------------------------- gl_once_t datatype -------------------------- */ + +typedef pthread_once_t gl_once_t; +# define gl_once_define(STORAGECLASS, NAME) \ + STORAGECLASS pthread_once_t NAME = PTHREAD_ONCE_INIT; +# define gl_once(NAME, INITFUNCTION) \ + do \ + { \ + if (pthread_in_use ()) \ + { \ + if (pthread_once (&NAME, INITFUNCTION) != 0) \ + abort (); \ + } \ + else \ + { \ + if (glthread_once_singlethreaded (&NAME)) \ + INITFUNCTION (); \ + } \ + } \ + while (0) +extern int glthread_once_singlethreaded (pthread_once_t *once_control); + #endif /* ========================================================================= */ @@ -322,6 +377,7 @@ extern void glthread_recursive_lock_destroy (gl_recursive_lock_t *lock); # pragma weak pth_rwlock_init # pragma weak pth_rwlock_acquire # pragma weak pth_rwlock_release +# pragma weak pth_once # pragma weak pth_cancel # define pth_in_use() (pth_cancel != NULL) @@ -338,7 +394,9 @@ typedef pth_mutex_t gl_lock_t; # define gl_lock_define(STORAGECLASS, NAME) \ STORAGECLASS pth_mutex_t NAME; # define gl_lock_define_initialized(STORAGECLASS, NAME) \ - STORAGECLASS pth_mutex_t NAME = PTH_MUTEX_INIT; + STORAGECLASS pth_mutex_t NAME = gl_lock_initializer; +# define gl_lock_initializer \ + PTH_MUTEX_INIT # define gl_lock_init(NAME) \ if (pth_in_use() && !pth_mutex_init (&NAME)) abort () # define gl_lock_lock(NAME) \ @@ -354,7 +412,9 @@ typedef pth_rwlock_t gl_rwlock_t; # define gl_rwlock_define(STORAGECLASS, NAME) \ STORAGECLASS pth_rwlock_t NAME; # define gl_rwlock_define_initialized(STORAGECLASS, NAME) \ - STORAGECLASS pth_rwlock_t NAME = PTH_RWLOCK_INIT; + STORAGECLASS pth_rwlock_t NAME = gl_rwlock_initializer; +# define gl_rwlock_initializer \ + PTH_RWLOCK_INIT # define gl_rwlock_init(NAME) \ if (pth_in_use() && !pth_rwlock_init (&NAME)) abort () # define gl_rwlock_rdlock(NAME) \ @@ -373,7 +433,9 @@ typedef pth_mutex_t gl_recursive_lock_t; # define gl_recursive_lock_define(STORAGECLASS, NAME) \ STORAGECLASS pth_mutex_t NAME; # define gl_recursive_lock_define_initialized(STORAGECLASS, NAME) \ - STORAGECLASS pth_mutex_t NAME = PTH_MUTEX_INIT; + STORAGECLASS pth_mutex_t NAME = gl_recursive_lock_initializer; +# define gl_recursive_lock_initializer \ + PTH_MUTEX_INIT # define gl_recursive_lock_init(NAME) \ if (pth_in_use() && !pth_mutex_init (&NAME)) abort () # define gl_recursive_lock_lock(NAME) \ @@ -383,6 +445,30 @@ typedef pth_mutex_t gl_recursive_lock_t; # define gl_recursive_lock_destroy(NAME) \ (void)(&NAME) +/* -------------------------- gl_once_t datatype -------------------------- */ + +typedef pth_once_t gl_once_t; +# define gl_once_define(STORAGECLASS, NAME) \ + STORAGECLASS pth_once_t NAME = PTH_ONCE_INIT; +# define gl_once(NAME, INITFUNCTION) \ + do \ + { \ + if (pth_in_use ()) \ + { \ + void (*gl_once_temp) (void) = INITFUNCTION; \ + if (!pth_once (&NAME, glthread_once_call, &gl_once_temp)) \ + abort (); \ + } \ + else \ + { \ + if (glthread_once_singlethreaded (&NAME)) \ + INITFUNCTION (); \ + } \ + } \ + while (0) +extern void glthread_once_call (void *arg); +extern int glthread_once_singlethreaded (pth_once_t *once_control); + #endif /* ========================================================================= */ @@ -425,7 +511,9 @@ typedef mutex_t gl_lock_t; # define gl_lock_define(STORAGECLASS, NAME) \ STORAGECLASS mutex_t NAME; # define gl_lock_define_initialized(STORAGECLASS, NAME) \ - STORAGECLASS mutex_t NAME = DEFAULTMUTEX; + STORAGECLASS mutex_t NAME = gl_lock_initializer; +# define gl_lock_initializer \ + DEFAULTMUTEX # define gl_lock_init(NAME) \ if (thread_in_use () && mutex_init (&NAME, USYNC_THREAD, NULL) != 0) abort () # define gl_lock_lock(NAME) \ @@ -441,7 +529,9 @@ typedef rwlock_t gl_rwlock_t; # define gl_rwlock_define(STORAGECLASS, NAME) \ STORAGECLASS rwlock_t NAME; # define gl_rwlock_define_initialized(STORAGECLASS, NAME) \ - STORAGECLASS rwlock_t NAME = DEFAULTRWLOCK; + STORAGECLASS rwlock_t NAME = gl_rwlock_initializer; +# define gl_rwlock_initializer \ + DEFAULTRWLOCK # define gl_rwlock_init(NAME) \ if (thread_in_use () && rwlock_init (&NAME, USYNC_THREAD, NULL) != 0) abort () # define gl_rwlock_rdlock(NAME) \ @@ -468,7 +558,9 @@ typedef struct # 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 = { DEFAULTMUTEX, (thread_t) 0, 0 }; + STORAGECLASS gl_recursive_lock_t NAME = gl_recursive_lock_initializer; +# define gl_recursive_lock_initializer \ + { DEFAULTMUTEX, (thread_t) 0, 0 } # define gl_recursive_lock_init(NAME) \ if (thread_in_use ()) glthread_recursive_lock_init (&NAME) # define gl_recursive_lock_lock(NAME) \ @@ -482,6 +574,33 @@ extern void glthread_recursive_lock_lock (gl_recursive_lock_t *lock); extern void glthread_recursive_lock_unlock (gl_recursive_lock_t *lock); extern void glthread_recursive_lock_destroy (gl_recursive_lock_t *lock); +/* -------------------------- gl_once_t datatype -------------------------- */ + +typedef struct + { + volatile int inited; + mutex_t mutex; + } + gl_once_t; +# define gl_once_define(STORAGECLASS, NAME) \ + STORAGECLASS gl_once_t NAME = { 0, DEFAULTMUTEX }; +# define gl_once(NAME, INITFUNCTION) \ + do \ + { \ + if (thread_in_use ()) \ + { \ + glthread_once (&NAME, INITFUNCTION); \ + } \ + else \ + { \ + if (glthread_once_singlethreaded (&NAME)) \ + INITFUNCTION (); \ + } \ + } \ + while (0) +extern void glthread_once (gl_once_t *once_control, void (*initfunction) (void)); +extern int glthread_once_singlethreaded (gl_once_t *once_control); + #endif /* ========================================================================= */ @@ -514,7 +633,9 @@ typedef struct # define gl_lock_define(STORAGECLASS, NAME) \ STORAGECLASS gl_lock_t NAME; # define gl_lock_define_initialized(STORAGECLASS, NAME) \ - STORAGECLASS gl_lock_t NAME = { { 0, -1 } }; + STORAGECLASS gl_lock_t NAME = gl_lock_initializer; +# define gl_lock_initializer \ + { { 0, -1 } } # define gl_lock_init(NAME) \ glthread_lock_init (&NAME) # define gl_lock_lock(NAME) \ @@ -554,7 +675,9 @@ typedef struct # define gl_rwlock_define(STORAGECLASS, NAME) \ STORAGECLASS gl_rwlock_t NAME; # define gl_rwlock_define_initialized(STORAGECLASS, NAME) \ - STORAGECLASS gl_rwlock_t NAME = { { 0, -1 } }; + STORAGECLASS gl_rwlock_t NAME = gl_rwlock_initializer; +# define gl_rwlock_initializer \ + { { 0, -1 } } # define gl_rwlock_init(NAME) \ glthread_rwlock_init (&NAME) # define gl_rwlock_rdlock(NAME) \ @@ -588,7 +711,9 @@ typedef struct # 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 = { { 0, -1 }, 0, 0 }; + STORAGECLASS gl_recursive_lock_t NAME = gl_recursive_lock_initializer; +# define gl_recursive_lock_initializer \ + { { 0, -1 }, 0, 0 } # define gl_recursive_lock_init(NAME) \ glthread_recursive_lock_init (&NAME) # define gl_recursive_lock_lock(NAME) \ @@ -602,6 +727,21 @@ extern void glthread_recursive_lock_lock (gl_recursive_lock_t *lock); extern void glthread_recursive_lock_unlock (gl_recursive_lock_t *lock); extern void glthread_recursive_lock_destroy (gl_recursive_lock_t *lock); +/* -------------------------- gl_once_t datatype -------------------------- */ + +typedef struct + { + volatile int inited; + volatile long started; + CRITICAL_SECTION lock; + } + gl_once_t; +# define gl_once_define(STORAGECLASS, NAME) \ + STORAGECLASS gl_once_t NAME = { -1, -1 }; +# define gl_once(NAME, INITFUNCTION) \ + glthread_once (&NAME, INITFUNCTION) +extern void glthread_once (gl_once_t *once_control, void (*initfunction) (void)); + #endif /* ========================================================================= */ @@ -638,4 +778,24 @@ typedef int gl_recursive_lock_t; # define gl_recursive_lock_lock(NAME) # define gl_recursive_lock_unlock(NAME) +/* -------------------------- gl_once_t datatype -------------------------- */ + +typedef int gl_once_t; +# define gl_once_define(STORAGECLASS, NAME) \ + STORAGECLASS gl_once_t NAME = 0; +# define gl_once(NAME, INITFUNCTION) \ + do \ + { \ + if (NAME == 0) \ + { \ + NAME = ~ 0; \ + INITFUNCTION (); \ + } \ + } \ + while (0) + #endif + +/* ========================================================================= */ + +#endif /* _LOCK_H */