blob: 387a9fe3c4bea2f9673311a78c41f4b1fbe24630 [file] [log] [blame]
Mark Slee9f0c6512007-02-28 23:58:26 +00001// Copyright (c) 2006- Facebook
2// Distributed under the Thrift Software License
3//
4// See accompanying file LICENSE or visit the Thrift site at:
5// http://developers.facebook.com/thrift/
6
Mark Sleef5f2be42006-09-05 21:05:31 +00007#ifndef _THRIFT_CONCURRENCY_MUTEX_H_
8#define _THRIFT_CONCURRENCY_MUTEX_H_ 1
Marc Slemko66949872006-07-15 01:52:39 +00009
boz19cee902007-09-22 23:08:11 +000010#include <boost/shared_ptr.hpp>
boz19cee902007-09-22 23:08:11 +000011
T Jake Lucianib5e62212009-01-31 22:36:20 +000012namespace apache { namespace thrift { namespace concurrency {
Marc Slemko66949872006-07-15 01:52:39 +000013
Mark Sleef5f2be42006-09-05 21:05:31 +000014/**
15 * A simple mutex class
16 *
Mark Sleef5f2be42006-09-05 21:05:31 +000017 * @version $Id:$
18 */
Marc Slemko66949872006-07-15 01:52:39 +000019class Mutex {
Marc Slemko66949872006-07-15 01:52:39 +000020 public:
David Reissc6dab612008-06-10 22:55:13 +000021 typedef void (*Initializer)(void*);
22
23 Mutex(Initializer init = DEFAULT_INITIALIZER);
boz19cee902007-09-22 23:08:11 +000024 virtual ~Mutex() {}
Marc Slemko66949872006-07-15 01:52:39 +000025 virtual void lock() const;
boz5362e702007-08-15 20:55:36 +000026 virtual bool trylock() const;
Marc Slemko66949872006-07-15 01:52:39 +000027 virtual void unlock() const;
28
David Reissc6dab612008-06-10 22:55:13 +000029 static void DEFAULT_INITIALIZER(void*);
David Reissc6dab612008-06-10 22:55:13 +000030 static void ADAPTIVE_INITIALIZER(void*);
David Reissc6dab612008-06-10 22:55:13 +000031 static void RECURSIVE_INITIALIZER(void*);
David Reissc6dab612008-06-10 22:55:13 +000032
Marc Slemko66949872006-07-15 01:52:39 +000033 private:
boz19cee902007-09-22 23:08:11 +000034
Marc Slemko66949872006-07-15 01:52:39 +000035 class impl;
yunfang14542962007-10-03 22:59:41 +000036 boost::shared_ptr<impl> impl_;
Marc Slemko66949872006-07-15 01:52:39 +000037};
38
bozcce81842007-07-06 22:27:52 +000039class ReadWriteMutex {
40public:
41 ReadWriteMutex();
boz19cee902007-09-22 23:08:11 +000042 virtual ~ReadWriteMutex() {}
bozcce81842007-07-06 22:27:52 +000043
44 // these get the lock and block until it is done successfully
45 virtual void acquireRead() const;
46 virtual void acquireWrite() const;
47
48 // these attempt to get the lock, returning false immediately if they fail
49 virtual bool attemptRead() const;
50 virtual bool attemptWrite() const;
51
52 // this releases both read and write locks
53 virtual void release() const;
David Reiss0c90f6f2008-02-06 22:18:40 +000054
bozcce81842007-07-06 22:27:52 +000055private:
boz19cee902007-09-22 23:08:11 +000056
bozcce81842007-07-06 22:27:52 +000057 class impl;
yunfang14542962007-10-03 22:59:41 +000058 boost::shared_ptr<impl> impl_;
bozcce81842007-07-06 22:27:52 +000059};
60
Mark Slee85287d32007-07-09 19:50:30 +000061class Guard {
David Reiss0c90f6f2008-02-06 22:18:40 +000062 public:
bozcce81842007-07-06 22:27:52 +000063 Guard(const Mutex& value) : mutex_(value) {
Mark Slee2f6404d2006-10-10 01:37:40 +000064 mutex_.lock();
Marc Slemko66949872006-07-15 01:52:39 +000065 }
bozcce81842007-07-06 22:27:52 +000066 ~Guard() {
Mark Slee2f6404d2006-10-10 01:37:40 +000067 mutex_.unlock();
Marc Slemko66949872006-07-15 01:52:39 +000068 }
69
70 private:
Mark Slee2f6404d2006-10-10 01:37:40 +000071 const Mutex& mutex_;
Marc Slemko66949872006-07-15 01:52:39 +000072};
73
yunfanga36f5db2007-07-14 01:23:05 +000074class RWGuard {
David Reiss0c90f6f2008-02-06 22:18:40 +000075 public:
yunfanga36f5db2007-07-14 01:23:05 +000076 RWGuard(const ReadWriteMutex& value, bool write = 0) : rw_mutex_(value) {
77 if (write) {
78 rw_mutex_.acquireWrite();
David Reiss96d23882007-07-26 21:10:32 +000079 } else {
yunfanga36f5db2007-07-14 01:23:05 +000080 rw_mutex_.acquireRead();
David Reiss96d23882007-07-26 21:10:32 +000081 }
David Reiss0c90f6f2008-02-06 22:18:40 +000082 }
yunfanga36f5db2007-07-14 01:23:05 +000083 ~RWGuard() {
84 rw_mutex_.release();
David Reiss0c90f6f2008-02-06 22:18:40 +000085 }
86 private:
boz19cee902007-09-22 23:08:11 +000087 const ReadWriteMutex& rw_mutex_;
David Reiss0c90f6f2008-02-06 22:18:40 +000088};
yunfanga36f5db2007-07-14 01:23:05 +000089
Marc Slemko66949872006-07-15 01:52:39 +000090
David Reisseaa61e42007-12-20 21:42:05 +000091// A little hack to prevent someone from trying to do "Guard(m);"
92// Sorry for polluting the global namespace, but I think it's worth it.
93#define Guard(m) incorrect_use_of_Guard(m)
94#define RWGuard(m) incorrect_use_of_RWGuard(m)
95
96
T Jake Lucianib5e62212009-01-31 22:36:20 +000097}}} // apache::thrift::concurrency
Marc Slemko66949872006-07-15 01:52:39 +000098
Mark Sleef5f2be42006-09-05 21:05:31 +000099#endif // #ifndef _THRIFT_CONCURRENCY_MUTEX_H_