ConcurrentJSLock.h [plain text]
#pragma once
#include "DeferGC.h"
#include <wtf/Lock.h>
#include <wtf/NoLock.h>
#include <wtf/Optional.h>
namespace JSC {
#if ENABLE(CONCURRENT_JS)
typedef Lock ConcurrentJSLock;
typedef LockHolder ConcurrentJSLockerImpl;
#else
typedef NoLock ConcurrentJSLock;
typedef NoLockLocker ConcurrentJSLockerImpl;
#endif
class ConcurrentJSLockerBase : public AbstractLocker {
WTF_MAKE_NONCOPYABLE(ConcurrentJSLockerBase);
public:
explicit ConcurrentJSLockerBase(ConcurrentJSLock& lockable)
: m_locker(&lockable)
{
}
explicit ConcurrentJSLockerBase(ConcurrentJSLock* lockable)
: m_locker(lockable)
{
}
explicit ConcurrentJSLockerBase(NoLockingNecessaryTag)
: m_locker(NoLockingNecessary)
{
}
~ConcurrentJSLockerBase()
{
}
void unlockEarly()
{
m_locker.unlockEarly();
}
private:
ConcurrentJSLockerImpl m_locker;
};
class GCSafeConcurrentJSLocker : public ConcurrentJSLockerBase {
public:
GCSafeConcurrentJSLocker(ConcurrentJSLock& lockable, Heap& heap)
: ConcurrentJSLockerBase(lockable)
, m_deferGC(heap)
{
}
GCSafeConcurrentJSLocker(ConcurrentJSLock* lockable, Heap& heap)
: ConcurrentJSLockerBase(lockable)
, m_deferGC(heap)
{
}
~GCSafeConcurrentJSLocker()
{
unlockEarly();
}
private:
DeferGC m_deferGC;
};
class ConcurrentJSLocker : public ConcurrentJSLockerBase {
public:
ConcurrentJSLocker(ConcurrentJSLock& lockable)
: ConcurrentJSLockerBase(lockable)
#if ENABLE(CONCURRENT_JS) && !defined(NDEBUG)
, m_disallowGC(std::in_place)
#endif
{
}
ConcurrentJSLocker(ConcurrentJSLock* lockable)
: ConcurrentJSLockerBase(lockable)
#if ENABLE(CONCURRENT_JS) && !defined(NDEBUG)
, m_disallowGC(std::in_place)
#endif
{
}
ConcurrentJSLocker(NoLockingNecessaryTag)
: ConcurrentJSLockerBase(NoLockingNecessary)
#if ENABLE(CONCURRENT_JS) && !defined(NDEBUG)
, m_disallowGC(std::nullopt)
#endif
{
}
ConcurrentJSLocker(int) = delete;
#if ENABLE(CONCURRENT_JS) && !defined(NDEBUG)
private:
std::optional<DisallowGC> m_disallowGC;
#endif
};
}