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