Arquivos
hhvm/hphp/util/lock.h
T
aalexandre 26178124a4 Eliminate int32, uint32, int16, uint16, int8, uint8.
This concludes the inttypes replacement.
These replacement have been mostly mechanical
with the use of cxx_replace.
2013-03-09 10:25:16 -08:00

196 linhas
5.1 KiB
C++

/*
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010- Facebook, Inc. (http://www.facebook.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
*/
#ifndef __LOCK_H__
#define __LOCK_H__
#include "mutex.h"
#include "synchronizable.h"
#include "synchronizable_multi.h"
namespace HPHP {
///////////////////////////////////////////////////////////////////////////////
/**
* Lock instrumentation for mutex stats.
*/
class LockProfiler {
public:
typedef void (*PFUNC_PROFILE)(const std::string &stack, int64_t elapsed_us);
static PFUNC_PROFILE s_pfunc_profile;
static bool s_profile;
static int s_profile_sampling;
LockProfiler(bool profile);
~LockProfiler();
private:
bool m_profiling;
#if defined(__APPLE__)
timeval m_lockTime;
#else
timespec m_lockTime;
#endif
};
///////////////////////////////////////////////////////////////////////////////
template <typename MutexT>
class BaseConditionalLock {
public:
BaseConditionalLock(MutexT &mutex, bool condition, bool profile = true)
: m_profiler(profile), m_mutex(mutex), m_acquired(false) {
if (condition) {
m_mutex.lock(); // must not throw
m_acquired = true;
}
}
~BaseConditionalLock() {
if (m_acquired) {
m_mutex.unlock(); // must not throw
}
}
private:
LockProfiler m_profiler;
MutexT& m_mutex;
bool m_acquired;
};
class ConditionalLock : public BaseConditionalLock<Mutex> {
public:
ConditionalLock(Mutex &mutex,
bool condition, bool profile = true)
: BaseConditionalLock<Mutex>(mutex, condition, profile)
{}
ConditionalLock(Synchronizable *obj,
bool condition, bool profile = true)
: BaseConditionalLock<Mutex>(obj->getMutex(), condition, profile)
{}
ConditionalLock(SynchronizableMulti *obj,
bool condition, bool profile = true)
: BaseConditionalLock<Mutex>(obj->getMutex(), condition, profile)
{}
};
/**
* Just a helper class that automatically unlocks a mutex when it goes out of
* scope.
*
* {
* Lock lock(mutex);
* // inside lock
* } // unlock here
*/
class Lock : public ConditionalLock {
public:
Lock(Mutex &mutex, bool profile = true)
: ConditionalLock(mutex, true, profile) {}
Lock(Synchronizable *obj, bool profile = true)
: ConditionalLock(obj, true, profile) {}
Lock(SynchronizableMulti *obj, bool profile = true)
: ConditionalLock(obj, true, profile) {}
};
class ScopedUnlock {
public:
ScopedUnlock(Mutex &mutex) : m_mutex(mutex) {
m_mutex.unlock();
}
ScopedUnlock(Synchronizable *obj) : m_mutex(obj->getMutex()) {
m_mutex.unlock();
}
ScopedUnlock(SynchronizableMulti *obj) : m_mutex(obj->getMutex()) {
m_mutex.unlock();
}
~ScopedUnlock() {
m_mutex.lock();
}
private:
Mutex &m_mutex;
};
class SimpleConditionalLock : public BaseConditionalLock<SimpleMutex> {
public:
SimpleConditionalLock(SimpleMutex &mutex,
bool condition, bool profile = true)
: BaseConditionalLock<SimpleMutex>(mutex, condition, profile)
{
if (condition) {
mutex.assertOwnedBySelf();
}
}
};
class SimpleLock : public SimpleConditionalLock {
public:
SimpleLock(SimpleMutex &mutex, bool profile = true)
: SimpleConditionalLock(mutex, true, profile) {}
};
///////////////////////////////////////////////////////////////////////////////
class ConditionalReadLock {
public:
ConditionalReadLock(ReadWriteMutex &mutex, bool condition,
bool profile = true)
: m_profiler(profile), m_mutex(mutex), m_acquired(false) {
if (condition) {
m_mutex.acquireRead();
m_acquired = true;
}
}
~ConditionalReadLock() {
if (m_acquired) {
m_mutex.release();
}
}
private:
LockProfiler m_profiler;
ReadWriteMutex &m_mutex;
bool m_acquired;
};
class ReadLock : public ConditionalReadLock {
public:
ReadLock(ReadWriteMutex &mutex, bool profile = true)
: ConditionalReadLock(mutex, true, profile) {}
};
class WriteLock {
public:
WriteLock(ReadWriteMutex &mutex, bool profile = true)
: m_profiler(profile), m_mutex(mutex) {
m_mutex.acquireWrite();
}
~WriteLock() {
m_mutex.release();
}
private:
LockProfiler m_profiler;
ReadWriteMutex &m_mutex;
};
///////////////////////////////////////////////////////////////////////////////
}
#endif // __LOCK_H__