summaryrefslogtreecommitdiff
path: root/Source/WTF/wtf/Locker.h
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2017-06-27 06:07:23 +0000
commit1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch)
tree46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WTF/wtf/Locker.h
parent32761a6cee1d0dee366b885b7b9c777e67885688 (diff)
downloadWebKitGtk-tarball-master.tar.gz
Diffstat (limited to 'Source/WTF/wtf/Locker.h')
-rw-r--r--Source/WTF/wtf/Locker.h81
1 files changed, 77 insertions, 4 deletions
diff --git a/Source/WTF/wtf/Locker.h b/Source/WTF/wtf/Locker.h
index ad88546fd..ca41f3028 100644
--- a/Source/WTF/wtf/Locker.h
+++ b/Source/WTF/wtf/Locker.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008, 2013 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2013, 2016 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -10,7 +10,7 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
- * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
+ * 3. Neither the name of Apple Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
@@ -28,26 +28,81 @@
#ifndef Locker_h
#define Locker_h
+#include <wtf/Assertions.h>
#include <wtf/Noncopyable.h>
namespace WTF {
-template <typename T> class Locker {
- WTF_MAKE_NONCOPYABLE(Locker);
+enum NoLockingNecessaryTag { NoLockingNecessary };
+
+class AbstractLocker {
+ WTF_MAKE_NONCOPYABLE(AbstractLocker);
+public:
+ AbstractLocker(NoLockingNecessaryTag)
+ {
+ }
+
+protected:
+ AbstractLocker()
+ {
+ }
+};
+
+template <typename T> class Locker : public AbstractLocker {
public:
explicit Locker(T& lockable) : m_lockable(&lockable) { lock(); }
explicit Locker(T* lockable) : m_lockable(lockable) { lock(); }
+
+ // You should be wary of using this constructor. It's only applicable
+ // in places where there is a locking protocol for a particular object
+ // but it's not necessary to engage in that protocol yet. For example,
+ // this often happens when an object is newly allocated and it can not
+ // be accessed concurrently.
+ Locker(NoLockingNecessaryTag) : m_lockable(nullptr) { }
+
+ Locker(int) = delete;
+
~Locker()
{
if (m_lockable)
m_lockable->unlock();
}
+ static Locker tryLock(T& lockable)
+ {
+ Locker result(NoLockingNecessary);
+ if (lockable.tryLock()) {
+ result.m_lockable = &lockable;
+ return result;
+ }
+ return result;
+ }
+
+ explicit operator bool() const { return !!m_lockable; }
+
void unlockEarly()
{
m_lockable->unlock();
m_lockable = 0;
}
+
+ // It's great to be able to pass lockers around. It enables custom locking adaptors like
+ // JSC::LockDuringMarking.
+ Locker(Locker&& other)
+ : m_lockable(other.m_lockable)
+ {
+ other.m_lockable = nullptr;
+ }
+
+ Locker& operator=(Locker&& other)
+ {
+ if (m_lockable)
+ m_lockable->unlock();
+ m_lockable = other.m_lockable;
+ other.m_lockable = nullptr;
+ return *this;
+ }
+
private:
void lock()
{
@@ -58,8 +113,26 @@ private:
T* m_lockable;
};
+// Use this lock scope like so:
+// auto locker = holdLock(lock);
+template<typename LockType>
+Locker<LockType> holdLock(LockType& lock)
+{
+ return Locker<LockType>(lock);
+}
+
+template<typename LockType>
+Locker<LockType> tryHoldLock(LockType& lock)
+{
+ return Locker<LockType>::tryLock(lock);
+}
+
}
+using WTF::AbstractLocker;
using WTF::Locker;
+using WTF::NoLockingNecessaryTag;
+using WTF::NoLockingNecessary;
+using WTF::holdLock;
#endif