blob: a33b9952d04b6367490b744024be88d6d27825d6 [file] [log] [blame]
David Reissea2cba82009-03-30 21:35:00 +00001/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
Mark Slee9f0c6512007-02-28 23:58:26 +000019
Mark Sleef5f2be42006-09-05 21:05:31 +000020#ifndef _THRIFT_CONCURRENCY_MUTEX_H_
21#define _THRIFT_CONCURRENCY_MUTEX_H_ 1
Marc Slemko66949872006-07-15 01:52:39 +000022
boz19cee902007-09-22 23:08:11 +000023#include <boost/shared_ptr.hpp>
boz19cee902007-09-22 23:08:11 +000024
T Jake Lucianib5e62212009-01-31 22:36:20 +000025namespace apache { namespace thrift { namespace concurrency {
Marc Slemko66949872006-07-15 01:52:39 +000026
Mark Sleef5f2be42006-09-05 21:05:31 +000027/**
28 * A simple mutex class
29 *
Mark Sleef5f2be42006-09-05 21:05:31 +000030 * @version $Id:$
31 */
Marc Slemko66949872006-07-15 01:52:39 +000032class Mutex {
Marc Slemko66949872006-07-15 01:52:39 +000033 public:
David Reissc6dab612008-06-10 22:55:13 +000034 typedef void (*Initializer)(void*);
35
36 Mutex(Initializer init = DEFAULT_INITIALIZER);
boz19cee902007-09-22 23:08:11 +000037 virtual ~Mutex() {}
Marc Slemko66949872006-07-15 01:52:39 +000038 virtual void lock() const;
boz5362e702007-08-15 20:55:36 +000039 virtual bool trylock() const;
Marc Slemko66949872006-07-15 01:52:39 +000040 virtual void unlock() const;
41
David Reissb9db49c2010-03-09 05:19:30 +000042 void* getUnderlyingImpl() const;
43
David Reissc6dab612008-06-10 22:55:13 +000044 static void DEFAULT_INITIALIZER(void*);
David Reissc6dab612008-06-10 22:55:13 +000045 static void ADAPTIVE_INITIALIZER(void*);
David Reissc6dab612008-06-10 22:55:13 +000046 static void RECURSIVE_INITIALIZER(void*);
David Reissc6dab612008-06-10 22:55:13 +000047
Marc Slemko66949872006-07-15 01:52:39 +000048 private:
boz19cee902007-09-22 23:08:11 +000049
Marc Slemko66949872006-07-15 01:52:39 +000050 class impl;
yunfang14542962007-10-03 22:59:41 +000051 boost::shared_ptr<impl> impl_;
Marc Slemko66949872006-07-15 01:52:39 +000052};
53
bozcce81842007-07-06 22:27:52 +000054class ReadWriteMutex {
55public:
56 ReadWriteMutex();
boz19cee902007-09-22 23:08:11 +000057 virtual ~ReadWriteMutex() {}
bozcce81842007-07-06 22:27:52 +000058
59 // these get the lock and block until it is done successfully
60 virtual void acquireRead() const;
61 virtual void acquireWrite() const;
62
63 // these attempt to get the lock, returning false immediately if they fail
64 virtual bool attemptRead() const;
65 virtual bool attemptWrite() const;
66
67 // this releases both read and write locks
68 virtual void release() const;
David Reiss0c90f6f2008-02-06 22:18:40 +000069
bozcce81842007-07-06 22:27:52 +000070private:
boz19cee902007-09-22 23:08:11 +000071
bozcce81842007-07-06 22:27:52 +000072 class impl;
yunfang14542962007-10-03 22:59:41 +000073 boost::shared_ptr<impl> impl_;
bozcce81842007-07-06 22:27:52 +000074};
75
Mark Slee85287d32007-07-09 19:50:30 +000076class Guard {
David Reiss0c90f6f2008-02-06 22:18:40 +000077 public:
bozcce81842007-07-06 22:27:52 +000078 Guard(const Mutex& value) : mutex_(value) {
Mark Slee2f6404d2006-10-10 01:37:40 +000079 mutex_.lock();
Marc Slemko66949872006-07-15 01:52:39 +000080 }
bozcce81842007-07-06 22:27:52 +000081 ~Guard() {
Mark Slee2f6404d2006-10-10 01:37:40 +000082 mutex_.unlock();
Marc Slemko66949872006-07-15 01:52:39 +000083 }
84
85 private:
Mark Slee2f6404d2006-10-10 01:37:40 +000086 const Mutex& mutex_;
Marc Slemko66949872006-07-15 01:52:39 +000087};
88
David Reisse96fa552010-03-09 05:19:37 +000089
90// Can be used as second argument to RWGuard to make code more readable
91// as to whether we're doing acquireRead() or acquireWrite().
92enum RWGuardType {
93 RW_READ = 0,
94 RW_WRITE = 1,
95};
96
97
yunfanga36f5db2007-07-14 01:23:05 +000098class RWGuard {
David Reiss0c90f6f2008-02-06 22:18:40 +000099 public:
David Reisse96fa552010-03-09 05:19:37 +0000100 RWGuard(const ReadWriteMutex& value, bool write = false)
101 : rw_mutex_(value) {
yunfanga36f5db2007-07-14 01:23:05 +0000102 if (write) {
103 rw_mutex_.acquireWrite();
David Reiss96d23882007-07-26 21:10:32 +0000104 } else {
yunfanga36f5db2007-07-14 01:23:05 +0000105 rw_mutex_.acquireRead();
David Reiss96d23882007-07-26 21:10:32 +0000106 }
David Reiss0c90f6f2008-02-06 22:18:40 +0000107 }
David Reisse96fa552010-03-09 05:19:37 +0000108
109 RWGuard(const ReadWriteMutex& value, RWGuardType type)
110 : rw_mutex_(value) {
111 if (type == RW_WRITE) {
112 rw_mutex_.acquireWrite();
113 } else {
114 rw_mutex_.acquireRead();
115 }
116 }
yunfanga36f5db2007-07-14 01:23:05 +0000117 ~RWGuard() {
118 rw_mutex_.release();
David Reiss0c90f6f2008-02-06 22:18:40 +0000119 }
120 private:
boz19cee902007-09-22 23:08:11 +0000121 const ReadWriteMutex& rw_mutex_;
David Reiss0c90f6f2008-02-06 22:18:40 +0000122};
yunfanga36f5db2007-07-14 01:23:05 +0000123
Marc Slemko66949872006-07-15 01:52:39 +0000124
David Reisseaa61e42007-12-20 21:42:05 +0000125// A little hack to prevent someone from trying to do "Guard(m);"
David Reissbe378f22009-05-07 00:41:18 +0000126// Such a use is invalid because the temporary Guard object is
127// destoryed at the end of the line, releasing the lock.
David Reisseaa61e42007-12-20 21:42:05 +0000128// Sorry for polluting the global namespace, but I think it's worth it.
129#define Guard(m) incorrect_use_of_Guard(m)
130#define RWGuard(m) incorrect_use_of_RWGuard(m)
131
132
T Jake Lucianib5e62212009-01-31 22:36:20 +0000133}}} // apache::thrift::concurrency
Marc Slemko66949872006-07-15 01:52:39 +0000134
Mark Sleef5f2be42006-09-05 21:05:31 +0000135#endif // #ifndef _THRIFT_CONCURRENCY_MUTEX_H_