?? lock.h
字號:
/* Locking in multithreaded situations. Copyright (C) 2005-2006 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU Library 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 Library General Public License for more details. You should have received a copy of the GNU Library 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. *//* Written by Bruno Haible <bruno@clisp.org>, 2005. Based on GCC's gthr-posix.h, gthr-posix95.h, gthr-solaris.h, gthr-win32.h. *//* This file contains locking primitives for use with a given thread library. It does not contain primitives for creating threads or for other synchronization primitives. Normal (non-recursive) locks: Type: gl_lock_t Declaration: gl_lock_define(extern, name) Initializer: gl_lock_define_initialized(, name) Initialization: gl_lock_init (name); Taking the lock: gl_lock_lock (name); Releasing the lock: gl_lock_unlock (name); De-initialization: gl_lock_destroy (name); Read-Write (non-recursive) locks: Type: gl_rwlock_t Declaration: gl_rwlock_define(extern, name) Initializer: gl_rwlock_define_initialized(, name) Initialization: gl_rwlock_init (name); Taking the lock: gl_rwlock_rdlock (name); gl_rwlock_wrlock (name); Releasing the lock: gl_rwlock_unlock (name); De-initialization: gl_rwlock_destroy (name); Recursive locks: Type: gl_recursive_lock_t Declaration: gl_recursive_lock_define(extern, name) Initializer: gl_recursive_lock_define_initialized(, name) Initialization: gl_recursive_lock_init (name); 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/* Use the POSIX threads library. */# include <pthread.h># include <stdlib.h># ifdef __cplusplusextern "C" {# endif# 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. *//* Weak references avoid dragging in external libraries if the other parts of the program don't use them. Here we use them, because we don't want every program that uses libintl to depend on libpthread. This assumes that libpthread would not be loaded after libintl; i.e. if libintl is loaded first, by an executable that does not depend on libpthread, and then a module is dynamically loaded that depends on libpthread, libintl will not be multithread-safe. *//* The way to test at runtime whether libpthread is present is to test whether a function pointer's value, such as &pthread_mutex_init, is non-NULL. However, some versions of GCC have a bug through which, in PIC mode, &foo != NULL always evaluates to true if there is a direct call to foo(...) in the same function. To avoid this, we test the address of a function in libpthread that we don't use. */# pragma weak pthread_mutex_init# pragma weak pthread_mutex_lock# pragma weak pthread_mutex_unlock# pragma weak pthread_mutex_destroy# pragma weak pthread_rwlock_init# pragma weak pthread_rwlock_rdlock# 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# pragma weak pthread_cond_broadcast# pragma weak pthread_cond_destroy# pragma weak pthread_mutexattr_init# pragma weak pthread_mutexattr_settype# pragma weak pthread_mutexattr_destroy# ifndef pthread_self# pragma weak pthread_self# endif# if !PTHREAD_IN_USE_DETECTION_HARD# pragma weak pthread_cancel# define pthread_in_use() (pthread_cancel != NULL)# endif# else# if !PTHREAD_IN_USE_DETECTION_HARD# define pthread_in_use() 1# endif# endif/* -------------------------- gl_lock_t datatype -------------------------- */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 = 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) \ if (pthread_in_use () && pthread_mutex_lock (&NAME) != 0) abort ()# define gl_lock_unlock(NAME) \ if (pthread_in_use () && pthread_mutex_unlock (&NAME) != 0) abort ()# define gl_lock_destroy(NAME) \ if (pthread_in_use () && pthread_mutex_destroy (&NAME) != 0) abort ()/* ------------------------- gl_rwlock_t datatype ------------------------- */# if HAVE_PTHREAD_RWLOCK# ifdef PTHREAD_RWLOCK_INITIALIZERtypedef 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 = 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) \ if (pthread_in_use () && pthread_rwlock_rdlock (&NAME) != 0) abort ()# define gl_rwlock_wrlock(NAME) \ if (pthread_in_use () && pthread_rwlock_wrlock (&NAME) != 0) abort ()# define gl_rwlock_unlock(NAME) \ if (pthread_in_use () && pthread_rwlock_unlock (&NAME) != 0) abort ()# define gl_rwlock_destroy(NAME) \ if (pthread_in_use () && pthread_rwlock_destroy (&NAME) != 0) abort ()# elsetypedef struct { int initialized; pthread_mutex_t guard; /* protects the initialization */ pthread_rwlock_t rwlock; /* read-write lock */ } 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, PTHREAD_MUTEX_INITIALIZER }# define gl_rwlock_init(NAME) \ if (pthread_in_use ()) glthread_rwlock_init (&NAME)# define gl_rwlock_rdlock(NAME) \ if (pthread_in_use ()) glthread_rwlock_rdlock (&NAME)# define gl_rwlock_wrlock(NAME) \ if (pthread_in_use ()) glthread_rwlock_wrlock (&NAME)# define gl_rwlock_unlock(NAME) \ if (pthread_in_use ()) glthread_rwlock_unlock (&NAME)# define gl_rwlock_destroy(NAME) \ if (pthread_in_use ()) glthread_rwlock_destroy (&NAME)extern void glthread_rwlock_init (gl_rwlock_t *lock);extern void glthread_rwlock_rdlock (gl_rwlock_t *lock);extern void glthread_rwlock_wrlock (gl_rwlock_t *lock);extern void glthread_rwlock_unlock (gl_rwlock_t *lock);extern void glthread_rwlock_destroy (gl_rwlock_t *lock);# endif# elsetypedef struct { pthread_mutex_t lock; /* protects the remaining fields */ pthread_cond_t waiting_readers; /* waiting readers */ pthread_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 \ { 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) \ if (pthread_in_use ()) glthread_rwlock_rdlock (&NAME)# define gl_rwlock_wrlock(NAME) \ if (pthread_in_use ()) glthread_rwlock_wrlock (&NAME)# define gl_rwlock_unlock(NAME) \ if (pthread_in_use ()) glthread_rwlock_unlock (&NAME)# define gl_rwlock_destroy(NAME) \ if (pthread_in_use ()) glthread_rwlock_destroy (&NAME)extern void glthread_rwlock_init (gl_rwlock_t *lock);extern void glthread_rwlock_rdlock (gl_rwlock_t *lock);extern void glthread_rwlock_wrlock (gl_rwlock_t *lock);extern void glthread_rwlock_unlock (gl_rwlock_t *lock);extern void glthread_rwlock_destroy (gl_rwlock_t *lock);# endif/* --------------------- gl_recursive_lock_t datatype --------------------- */# if HAVE_PTHREAD_MUTEX_RECURSIVE# if defined PTHREAD_RECURSIVE_MUTEX_INITIALIZER || defined PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NPtypedef 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_initializer \ PTHREAD_RECURSIVE_MUTEX_INITIALIZER# else# 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 ()# define gl_recursive_lock_lock(NAME) \ if (pthread_in_use () && pthread_mutex_lock (&NAME) != 0) abort ()# define gl_recursive_lock_unlock(NAME) \ if (pthread_in_use () && pthread_mutex_unlock (&NAME) != 0) abort ()# define gl_recursive_lock_destroy(NAME) \ if (pthread_in_use () && pthread_mutex_destroy (&NAME) != 0) abort ()# else
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -