diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
commit | 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch) | |
tree | 46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WTF/wtf/Locker.h | |
parent | 32761a6cee1d0dee366b885b7b9c777e67885688 (diff) | |
download | WebKitGtk-tarball-master.tar.gz |
webkitgtk-2.16.5HEADwebkitgtk-2.16.5master
Diffstat (limited to 'Source/WTF/wtf/Locker.h')
-rw-r--r-- | Source/WTF/wtf/Locker.h | 81 |
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 |