FILENAME 3/4 - delete the old get_fun_path etc.
[hiphop-php.git] / hphp / util / lock.h
blob6452905e701307dc17a516ce5847123d7a8988de
1 /*
2 +----------------------------------------------------------------------+
3 | HipHop for PHP |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2010-present Facebook, Inc. (http://www.facebook.com) |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 3.01 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available through the world-wide-web at the following url: |
10 | http://www.php.net/license/3_01.txt |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
17 #pragma once
19 #include "hphp/util/mutex.h"
20 #include "hphp/util/synchronizable.h"
21 #include "hphp/util/synchronizable-multi.h"
23 namespace HPHP {
24 ///////////////////////////////////////////////////////////////////////////////
26 /**
27 * Lock instrumentation for mutex stats.
29 struct LockProfiler {
30 typedef void (*PFUNC_PROFILE)(const std::string &stack, int64_t elapsed_us);
31 static PFUNC_PROFILE s_pfunc_profile;
32 static bool s_profile;
33 static int s_profile_sampling;
35 explicit LockProfiler(bool profile);
36 ~LockProfiler();
38 private:
39 bool m_profiling;
40 timespec m_lockTime;
43 ///////////////////////////////////////////////////////////////////////////////
45 template <typename MutexT>
46 struct BaseConditionalLock {
47 BaseConditionalLock(MutexT &mutex, bool condition, bool profile = true)
48 : m_profiler(profile), m_mutex(mutex), m_acquired(false) {
49 if (condition) {
50 m_mutex.lock(); // must not throw
51 m_acquired = true;
54 ~BaseConditionalLock() {
55 if (m_acquired) {
56 m_mutex.unlock(); // must not throw
59 private:
60 LockProfiler m_profiler;
61 MutexT& m_mutex;
62 bool m_acquired;
65 struct ConditionalLock : BaseConditionalLock<Mutex> {
66 ConditionalLock(Mutex &mutex,
67 bool condition, bool profile = true)
68 : BaseConditionalLock<Mutex>(mutex, condition, profile)
70 ConditionalLock(Synchronizable *obj,
71 bool condition, bool profile = true)
72 : BaseConditionalLock<Mutex>(obj->getMutex(), condition, profile)
74 ConditionalLock(SynchronizableMulti *obj,
75 bool condition, bool profile = true)
76 : BaseConditionalLock<Mutex>(obj->getMutex(), condition, profile)
80 /**
81 * Just a helper class that automatically unlocks a mutex when it goes out of
82 * scope.
84 * {
85 * Lock lock(mutex);
86 * // inside lock
87 * } // unlock here
89 struct Lock : ConditionalLock {
90 explicit Lock(Mutex &mutex, bool profile = true)
91 : ConditionalLock(mutex, true, profile) {}
92 explicit Lock(Synchronizable *obj, bool profile = true)
93 : ConditionalLock(obj, true, profile) {}
94 explicit Lock(SynchronizableMulti *obj, bool profile = true)
95 : ConditionalLock(obj, true, profile) {}
98 struct ScopedUnlock {
99 explicit ScopedUnlock(Mutex &mutex) : m_mutex(mutex) {
100 m_mutex.unlock();
102 explicit ScopedUnlock(Synchronizable *obj) : m_mutex(obj->getMutex()) {
103 m_mutex.unlock();
105 explicit ScopedUnlock(SynchronizableMulti *obj) : m_mutex(obj->getMutex()) {
106 m_mutex.unlock();
109 ~ScopedUnlock() {
110 m_mutex.lock();
113 private:
114 Mutex &m_mutex;
117 struct SimpleConditionalLock : BaseConditionalLock<SimpleMutex> {
118 SimpleConditionalLock(SimpleMutex &mutex,
119 bool condition, bool profile = true)
120 : BaseConditionalLock<SimpleMutex>(mutex, condition, profile)
122 if (condition) {
123 mutex.assertOwnedBySelf();
128 struct SimpleLock : SimpleConditionalLock {
129 explicit SimpleLock(SimpleMutex &mutex, bool profile = true)
130 : SimpleConditionalLock(mutex, true, profile) {}
133 ///////////////////////////////////////////////////////////////////////////////
135 struct ReadLock {
136 explicit ReadLock(ReadWriteMutex& mutex, bool profile = true)
137 : m_profiler(profile)
138 , m_mutex(mutex)
140 m_mutex.acquireRead();
143 ReadLock(const ReadLock&) = delete;
144 ReadLock& operator=(const ReadLock&) = delete;
146 ~ReadLock() {
147 m_mutex.release();
150 private:
151 LockProfiler m_profiler;
152 ReadWriteMutex& m_mutex;
155 struct WriteLock {
156 explicit WriteLock(ReadWriteMutex& mutex, bool profile = true)
157 : m_profiler(profile)
158 , m_mutex(mutex)
160 m_mutex.acquireWrite();
163 WriteLock(const WriteLock&) = delete;
164 WriteLock& operator=(const WriteLock&) = delete;
166 ~WriteLock() {
167 m_mutex.release();
170 private:
171 LockProfiler m_profiler;
172 ReadWriteMutex& m_mutex;
175 ///////////////////////////////////////////////////////////////////////////////