12ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson// Copyright 2007 The RE2 Authors. All Rights Reserved. 22ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson// Use of this source code is governed by a BSD-style 32ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson// license that can be found in the LICENSE file. 42ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson 52ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson/* 62ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson * A simple mutex wrapper, supporting locks and read-write locks. 72ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson * You should assume the locks are *not* re-entrant. 82ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson */ 92ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson 102ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson#ifndef RE2_UTIL_MUTEX_H_ 112ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson#define RE2_UTIL_MUTEX_H_ 122ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson 132ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodsonnamespace re2 { 142ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson 152ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson#define HAVE_PTHREAD 1 162ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson#define HAVE_RWLOCK 1 172ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson 182ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson#if defined(NO_THREADS) 192ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson typedef int MutexType; // to keep a lock-count 202ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson#elif defined(HAVE_PTHREAD) && defined(HAVE_RWLOCK) 212ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson // Needed for pthread_rwlock_*. If it causes problems, you could take it 222ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson // out, but then you'd have to unset HAVE_RWLOCK (at least on linux -- it 232ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson // *does* cause problems for FreeBSD, or MacOSX, but isn't needed 242ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson // for locking there.) 252ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson# ifdef __linux__ 262ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson# undef _XOPEN_SOURCE 272ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson# define _XOPEN_SOURCE 500 // may be needed to get the rwlock calls 282ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson# endif 292ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson# include <pthread.h> 302ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson typedef pthread_rwlock_t MutexType; 312ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson#elif defined(HAVE_PTHREAD) 322ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson# include <pthread.h> 332ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson typedef pthread_mutex_t MutexType; 342ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson#elif defined(WIN32) 352ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson# define WIN32_LEAN_AND_MEAN // We only need minimal includes 362ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson# ifdef GMUTEX_TRYLOCK 372ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson // We need Windows NT or later for TryEnterCriticalSection(). If you 382ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson // don't need that functionality, you can remove these _WIN32_WINNT 392ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson // lines, and change TryLock() to assert(0) or something. 402ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson# ifndef _WIN32_WINNT 412ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson# define _WIN32_WINNT 0x0400 422ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson# endif 432ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson# endif 442ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson# include <windows.h> 452ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson typedef CRITICAL_SECTION MutexType; 462ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson#else 472ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson# error Need to implement mutex.h for your architecture, or #define NO_THREADS 482ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson#endif 492ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson 502ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodsonclass Mutex { 512ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson public: 522ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson // Create a Mutex that is not held by anybody. 532ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson inline Mutex(); 542ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson 552ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson // Destructor 562ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson inline ~Mutex(); 572ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson 582ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson inline void Lock(); // Block if needed until free then acquire exclusively 592ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson inline void Unlock(); // Release a lock acquired via Lock() 602ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson inline bool TryLock(); // If free, Lock() and return true, else return false 612ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson // Note that on systems that don't support read-write locks, these may 622ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson // be implemented as synonyms to Lock() and Unlock(). So you can use 632ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson // these for efficiency, but don't use them anyplace where being able 642ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson // to do shared reads is necessary to avoid deadlock. 652ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson inline void ReaderLock(); // Block until free or shared then acquire a share 662ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson inline void ReaderUnlock(); // Release a read share of this Mutex 672ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson inline void WriterLock() { Lock(); } // Acquire an exclusive lock 682ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson inline void WriterUnlock() { Unlock(); } // Release a lock from WriterLock() 692ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson inline void AssertHeld() { } 702ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson 712ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson private: 722ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson MutexType mutex_; 732ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson 742ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson // Catch the error of writing Mutex when intending MutexLock. 750d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin Mutex(Mutex *ignored); 762ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson // Disallow "evil" constructors 772ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson Mutex(const Mutex&); 782ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson void operator=(const Mutex&); 792ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson}; 802ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson 812ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson// Now the implementation of Mutex for various systems 822ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson#if defined(NO_THREADS) 832ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson 842ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson// When we don't have threads, we can be either reading or writing, 852ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson// but not both. We can have lots of readers at once (in no-threads 862ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson// mode, that's most likely to happen in recursive function calls), 872ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson// but only one writer. We represent this by having mutex_ be -1 when 882ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson// writing and a number > 0 when reading (and 0 when no lock is held). 892ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson// 902ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson// In debug mode, we assert these invariants, while in non-debug mode 912ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson// we do nothing, for efficiency. That's why everything is in an 922ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson// assert. 932ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson#include <assert.h> 942ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson 952ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian HodsonMutex::Mutex() : mutex_(0) { } 962ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian HodsonMutex::~Mutex() { assert(mutex_ == 0); } 972ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodsonvoid Mutex::Lock() { assert(--mutex_ == -1); } 982ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodsonvoid Mutex::Unlock() { assert(mutex_++ == -1); } 992ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodsonbool Mutex::TryLock() { if (mutex_) return false; Lock(); return true; } 1002ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodsonvoid Mutex::ReaderLock() { assert(++mutex_ > 0); } 1012ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodsonvoid Mutex::ReaderUnlock() { assert(mutex_-- > 0); } 1022ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson 1032ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson#elif defined(HAVE_PTHREAD) && defined(HAVE_RWLOCK) 1042ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson 1052ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson#include <stdlib.h> // for abort() 1062ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson#define SAFE_PTHREAD(fncall) do { if ((fncall) != 0) abort(); } while (0) 1072ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson 1082ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian HodsonMutex::Mutex() { SAFE_PTHREAD(pthread_rwlock_init(&mutex_, NULL)); } 1092ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian HodsonMutex::~Mutex() { SAFE_PTHREAD(pthread_rwlock_destroy(&mutex_)); } 1102ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodsonvoid Mutex::Lock() { SAFE_PTHREAD(pthread_rwlock_wrlock(&mutex_)); } 1112ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodsonvoid Mutex::Unlock() { SAFE_PTHREAD(pthread_rwlock_unlock(&mutex_)); } 1122ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodsonbool Mutex::TryLock() { return pthread_rwlock_trywrlock(&mutex_) == 0; } 1132ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodsonvoid Mutex::ReaderLock() { SAFE_PTHREAD(pthread_rwlock_rdlock(&mutex_)); } 1142ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodsonvoid Mutex::ReaderUnlock() { SAFE_PTHREAD(pthread_rwlock_unlock(&mutex_)); } 1152ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson 1162ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson#undef SAFE_PTHREAD 1172ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson 1182ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson#elif defined(HAVE_PTHREAD) 1192ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson 1202ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson#include <stdlib.h> // for abort() 1212ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson#define SAFE_PTHREAD(fncall) do { if ((fncall) != 0) abort(); } while (0) 1222ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson 1232ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian HodsonMutex::Mutex() { SAFE_PTHREAD(pthread_mutex_init(&mutex_, NULL)); } 1242ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian HodsonMutex::~Mutex() { SAFE_PTHREAD(pthread_mutex_destroy(&mutex_)); } 1252ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodsonvoid Mutex::Lock() { SAFE_PTHREAD(pthread_mutex_lock(&mutex_)); } 1262ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodsonvoid Mutex::Unlock() { SAFE_PTHREAD(pthread_mutex_unlock(&mutex_)); } 1272ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodsonbool Mutex::TryLock() { return pthread_mutex_trylock(&mutex_) == 0; } 1282ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodsonvoid Mutex::ReaderLock() { Lock(); } // we don't have read-write locks 1292ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodsonvoid Mutex::ReaderUnlock() { Unlock(); } 1302ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson#undef SAFE_PTHREAD 1312ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson 1322ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson#elif defined(WIN32) 1332ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson 1342ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian HodsonMutex::Mutex() { InitializeCriticalSection(&mutex_); } 1352ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian HodsonMutex::~Mutex() { DeleteCriticalSection(&mutex_); } 1362ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodsonvoid Mutex::Lock() { EnterCriticalSection(&mutex_); } 1372ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodsonvoid Mutex::Unlock() { LeaveCriticalSection(&mutex_); } 1382ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodsonbool Mutex::TryLock() { return TryEnterCriticalSection(&mutex_) != 0; } 1392ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodsonvoid Mutex::ReaderLock() { Lock(); } // we don't have read-write locks 1402ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodsonvoid Mutex::ReaderUnlock() { Unlock(); } 1412ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson 1422ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson#endif 1432ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson 1442ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson 1452ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson// -------------------------------------------------------------------------- 1462ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson// Some helper classes 1472ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson 1482ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson// MutexLock(mu) acquires mu when constructed and releases it when destroyed. 1492ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodsonclass MutexLock { 1502ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson public: 1512ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson explicit MutexLock(Mutex *mu) : mu_(mu) { mu_->Lock(); } 1522ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson ~MutexLock() { mu_->Unlock(); } 1532ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson private: 1542ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson Mutex * const mu_; 1552ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson // Disallow "evil" constructors 1562ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson MutexLock(const MutexLock&); 1572ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson void operator=(const MutexLock&); 1582ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson}; 1592ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson 1602ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson// ReaderMutexLock and WriterMutexLock do the same, for rwlocks 1612ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodsonclass ReaderMutexLock { 1622ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson public: 1632ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson explicit ReaderMutexLock(Mutex *mu) : mu_(mu) { mu_->ReaderLock(); } 1642ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson ~ReaderMutexLock() { mu_->ReaderUnlock(); } 1652ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson private: 1662ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson Mutex * const mu_; 1672ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson // Disallow "evil" constructors 1682ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson ReaderMutexLock(const ReaderMutexLock&); 1692ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson void operator=(const ReaderMutexLock&); 1702ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson}; 1712ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson 1722ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodsonclass WriterMutexLock { 1732ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson public: 1742ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson explicit WriterMutexLock(Mutex *mu) : mu_(mu) { mu_->WriterLock(); } 1752ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson ~WriterMutexLock() { mu_->WriterUnlock(); } 1762ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson private: 1772ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson Mutex * const mu_; 1782ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson // Disallow "evil" constructors 1792ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson WriterMutexLock(const WriterMutexLock&); 1802ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson void operator=(const WriterMutexLock&); 1812ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson}; 1822ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson 1832ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson// Catch bug where variable name is omitted, e.g. MutexLock (&mu); 1842ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson#define MutexLock(x) COMPILE_ASSERT(0, mutex_lock_decl_missing_var_name) 1852ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson#define ReaderMutexLock(x) COMPILE_ASSERT(0, rmutex_lock_decl_missing_var_name) 1862ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson#define WriterMutexLock(x) COMPILE_ASSERT(0, wmutex_lock_decl_missing_var_name) 1872ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson 1880d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin// Provide safe way to declare and use global, linker-initialized mutex. Sigh. 1890d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin#ifdef HAVE_PTHREAD 1900d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin 1910d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin#define GLOBAL_MUTEX(name) \ 1920d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin static pthread_mutex_t (name) = PTHREAD_MUTEX_INITIALIZER 1930d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin#define GLOBAL_MUTEX_LOCK(name) \ 1940d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin pthread_mutex_lock(&(name)) 1950d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin#define GLOBAL_MUTEX_UNLOCK(name) \ 1960d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin pthread_mutex_unlock(&(name)) 1970d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin 1980d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin#else 1990d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin 2000d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin#define GLOBAL_MUTEX(name) \ 2010d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin static Mutex name 2020d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin#define GLOBAL_MUTEX_LOCK(name) \ 2030d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin name.Lock() 2040d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin#define GLOBAL_MUTEX_UNLOCK(name) \ 2050d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin name.Unlock() 2060d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin 2070d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin#endif 2080d4c52358a1af421705c54bd8a9fdd8a30558a2eAlexander Gutkin 2092ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson} // namespace re2 2102ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson 2112ee91b4af4353b9e6a9d591c32fedfc58fd4ef35Ian Hodson#endif /* #define RE2_UTIL_MUTEX_H_ */ 212