diff options
author | David Reiss <dreiss@apache.org> | 2008-06-10 22:55:13 +0000 |
---|---|---|
committer | David Reiss <dreiss@apache.org> | 2008-06-10 22:55:13 +0000 |
commit | c6dab613003c704f072542f39214f7af64fc0412 (patch) | |
tree | 6cf0c32408e229af01a44f79023d29747ba6fde7 /lib/cpp | |
parent | e3a64923e9620ebf99ff51ed5bfcb366e503c79e (diff) | |
download | thrift-c6dab613003c704f072542f39214f7af64fc0412.tar.gz |
Thrift: Allow for alternative Mutex initializers.
Summary:
Add an argument to the Mutex constructor.
It takes a pointer to a function that initializes the internal pthread_mutex_t.
We provide initializers for default pthread_mutex_t (which is our default),
adaptive mutexes, and recursive mutexes.
Reviewed By: hzhao, psaab, mcslee
Test Plan: Built libthrift.
git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@666362 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'lib/cpp')
-rw-r--r-- | lib/cpp/src/concurrency/Mutex.cpp | 50 | ||||
-rw-r--r-- | lib/cpp/src/concurrency/Mutex.h | 12 |
2 files changed, 57 insertions, 5 deletions
diff --git a/lib/cpp/src/concurrency/Mutex.cpp b/lib/cpp/src/concurrency/Mutex.cpp index 87bfd354c..b160b670e 100644 --- a/lib/cpp/src/concurrency/Mutex.cpp +++ b/lib/cpp/src/concurrency/Mutex.cpp @@ -21,9 +21,8 @@ namespace facebook { namespace thrift { namespace concurrency { */ class Mutex::impl { public: - impl() : initialized_(false) { - int ret = pthread_mutex_init(&pthread_mutex_, NULL); - assert(ret == 0); + impl(Initializer init) : initialized_(false) { + init(&pthread_mutex_); initialized_ = true; } @@ -46,7 +45,7 @@ class Mutex::impl { mutable bool initialized_; }; -Mutex::Mutex() : impl_(new Mutex::impl()) {} +Mutex::Mutex(Initializer init) : impl_(new Mutex::impl(init)) {} void Mutex::lock() const { impl_->lock(); } @@ -54,6 +53,49 @@ bool Mutex::trylock() const { return impl_->trylock(); } void Mutex::unlock() const { impl_->unlock(); } +void Mutex::DEFAULT_INITIALIZER(void* arg) { + pthread_mutex_t* pthread_mutex = (pthread_mutex_t*)arg; + int ret = pthread_mutex_init(pthread_mutex, NULL); + assert(ret == 0); +} + +static void init_with_kind(pthread_mutex_t* mutex, int kind) { + pthread_mutexattr_t mutexattr; + int ret = pthread_mutexattr_init(&mutexattr); + assert(ret == 0); + + // Apparently, this can fail. Should we really be aborting? + ret = pthread_mutexattr_settype(&mutexattr, kind); + assert(ret == 0); + + ret = pthread_mutex_init(mutex, &mutexattr); + assert(ret == 0); + + ret = pthread_mutexattr_destroy(&mutexattr); + assert(ret == 0); +} + +#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP +void Mutex::ADAPTIVE_INITIALIZER(void* arg) { + // From mysql source: mysys/my_thr_init.c + // Set mutex type to "fast" a.k.a "adaptive" + // + // In this case the thread may steal the mutex from some other thread + // that is waiting for the same mutex. This will save us some + // context switches but may cause a thread to 'starve forever' while + // waiting for the mutex (not likely if the code within the mutex is + // short). + init_with_kind((pthread_mutex_t*)arg, PTHREAD_MUTEX_ADAPTIVE_NP); +} +#endif + +#ifdef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP +void Mutex::RECURSIVE_INITIALIZER(void* arg) { + init_with_kind((pthread_mutex_t*)arg, PTHREAD_MUTEX_RECURSIVE_NP); +} +#endif + + /** * Implementation of ReadWriteMutex class using POSIX rw lock * diff --git a/lib/cpp/src/concurrency/Mutex.h b/lib/cpp/src/concurrency/Mutex.h index e176628a7..7830d6867 100644 --- a/lib/cpp/src/concurrency/Mutex.h +++ b/lib/cpp/src/concurrency/Mutex.h @@ -19,12 +19,22 @@ namespace facebook { namespace thrift { namespace concurrency { */ class Mutex { public: - Mutex(); + typedef void (*Initializer)(void*); + + Mutex(Initializer init = DEFAULT_INITIALIZER); virtual ~Mutex() {} virtual void lock() const; virtual bool trylock() const; virtual void unlock() const; + static void DEFAULT_INITIALIZER(void*); +#ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP + static void ADAPTIVE_INITIALIZER(void*); +#endif +#ifdef PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP + static void RECURSIVE_INITIALIZER(void*); +#endif + private: class impl; |