X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=lib%2Fglthread%2Flock.h;fp=lib%2Fglthread%2Flock.h;h=34ff109680b1305838e903d163a916249fa31781;hb=a8a88eddaa90432e6ec1b8d9d5c9842bc91afd1d;hp=e64506b3d0f4fdb0eb33adb2eefe7a7ac3edaa09;hpb=20fcfc81ece044b8b0a6768ec6cf47be4e22a2e6;p=debian%2Fgzip diff --git a/lib/glthread/lock.h b/lib/glthread/lock.h index e64506b..34ff109 100644 --- a/lib/glthread/lock.h +++ b/lib/glthread/lock.h @@ -1,5 +1,5 @@ /* Locking in multithreaded situations. - Copyright (C) 2005-2016 Free Software Foundation, Inc. + Copyright (C) 2005-2018 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,7 +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, see . */ + along with this program; if not, see . */ /* Written by Bruno Haible , 2005. Based on GCC's gthr-posix.h, gthr-posix95.h, gthr-solaris.h, @@ -139,6 +139,11 @@ extern int glthread_in_use (void); # pragma weak pthread_mutexattr_init # pragma weak pthread_mutexattr_settype # pragma weak pthread_mutexattr_destroy +# pragma weak pthread_rwlockattr_init +# if __GNU_LIBRARY__ > 1 +# pragma weak pthread_rwlockattr_setkind_np +# endif +# pragma weak pthread_rwlockattr_destroy # ifndef pthread_self # pragma weak pthread_self # endif @@ -176,7 +181,7 @@ typedef pthread_mutex_t gl_lock_t; /* ------------------------- gl_rwlock_t datatype ------------------------- */ -# if HAVE_PTHREAD_RWLOCK +# if HAVE_PTHREAD_RWLOCK && (HAVE_PTHREAD_RWLOCK_RDLOCK_PREFER_WRITER || (defined PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP && (__GNU_LIBRARY__ > 1))) # ifdef PTHREAD_RWLOCK_INITIALIZER @@ -185,10 +190,18 @@ typedef pthread_rwlock_t gl_rwlock_t; STORAGECLASS pthread_rwlock_t NAME; # define gl_rwlock_define_initialized(STORAGECLASS, NAME) \ STORAGECLASS pthread_rwlock_t NAME = gl_rwlock_initializer; -# define gl_rwlock_initializer \ - PTHREAD_RWLOCK_INITIALIZER -# define glthread_rwlock_init(LOCK) \ - (pthread_in_use () ? pthread_rwlock_init (LOCK, NULL) : 0) +# if HAVE_PTHREAD_RWLOCK_RDLOCK_PREFER_WRITER +# define gl_rwlock_initializer \ + PTHREAD_RWLOCK_INITIALIZER +# define glthread_rwlock_init(LOCK) \ + (pthread_in_use () ? pthread_rwlock_init (LOCK, NULL) : 0) +# else /* glibc with bug https://sourceware.org/bugzilla/show_bug.cgi?id=13701 */ +# define gl_rwlock_initializer \ + PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP +# define glthread_rwlock_init(LOCK) \ + (pthread_in_use () ? glthread_rwlock_init_for_glibc (LOCK) : 0) +extern int glthread_rwlock_init_for_glibc (pthread_rwlock_t *lock); +# endif # define glthread_rwlock_rdlock(LOCK) \ (pthread_in_use () ? pthread_rwlock_rdlock (LOCK) : 0) # define glthread_rwlock_wrlock(LOCK) \ @@ -427,6 +440,9 @@ typedef pth_mutex_t gl_lock_t; /* ------------------------- gl_rwlock_t datatype ------------------------- */ +/* Pth pth_rwlock_acquire always prefers readers. No autoconf test so far. */ +# if HAVE_PTH_RWLOCK_ACQUIRE_PREFER_WRITER + typedef pth_rwlock_t gl_rwlock_t; # define gl_rwlock_define(STORAGECLASS, NAME) \ STORAGECLASS pth_rwlock_t NAME; @@ -445,6 +461,42 @@ typedef pth_rwlock_t gl_rwlock_t; # define glthread_rwlock_destroy(LOCK) \ ((void)(LOCK), 0) +# else + +typedef struct + { + int initialized; + pth_mutex_t lock; /* protects the remaining fields */ + pth_cond_t waiting_readers; /* waiting readers */ + pth_cond_t waiting_writers; /* waiting writers */ + unsigned int waiting_writers_count; /* number of waiting writers */ + int runcount; /* number of readers running, or -1 when a writer runs */ + } + gl_rwlock_t; +# define gl_rwlock_define(STORAGECLASS, NAME) \ + STORAGECLASS gl_rwlock_t NAME; +# define gl_rwlock_define_initialized(STORAGECLASS, NAME) \ + STORAGECLASS gl_rwlock_t NAME = gl_rwlock_initializer; +# define gl_rwlock_initializer \ + { 0 } +# define glthread_rwlock_init(LOCK) \ + (pth_in_use () ? glthread_rwlock_init_multithreaded (LOCK) : 0) +# define glthread_rwlock_rdlock(LOCK) \ + (pth_in_use () ? glthread_rwlock_rdlock_multithreaded (LOCK) : 0) +# define glthread_rwlock_wrlock(LOCK) \ + (pth_in_use () ? glthread_rwlock_wrlock_multithreaded (LOCK) : 0) +# define glthread_rwlock_unlock(LOCK) \ + (pth_in_use () ? glthread_rwlock_unlock_multithreaded (LOCK) : 0) +# define glthread_rwlock_destroy(LOCK) \ + (pth_in_use () ? glthread_rwlock_destroy_multithreaded (LOCK) : 0) +extern int glthread_rwlock_init_multithreaded (gl_rwlock_t *lock); +extern int glthread_rwlock_rdlock_multithreaded (gl_rwlock_t *lock); +extern int glthread_rwlock_wrlock_multithreaded (gl_rwlock_t *lock); +extern int glthread_rwlock_unlock_multithreaded (gl_rwlock_t *lock); +extern int glthread_rwlock_destroy_multithreaded (gl_rwlock_t *lock); + +# endif + /* --------------------- gl_recursive_lock_t datatype --------------------- */ /* In Pth, mutexes are recursive by default. */