summaryrefslogtreecommitdiff
path: root/Source/JavaScriptCore/runtime/JSLock.h
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2016-04-10 09:28:39 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2016-04-10 09:28:39 +0000
commit32761a6cee1d0dee366b885b7b9c777e67885688 (patch)
treed6bec92bebfb216f4126356e55518842c2f476a1 /Source/JavaScriptCore/runtime/JSLock.h
parenta4e969f4965059196ca948db781e52f7cfebf19e (diff)
downloadWebKitGtk-tarball-32761a6cee1d0dee366b885b7b9c777e67885688.tar.gz
webkitgtk-2.4.11webkitgtk-2.4.11
Diffstat (limited to 'Source/JavaScriptCore/runtime/JSLock.h')
-rw-r--r--Source/JavaScriptCore/runtime/JSLock.h196
1 files changed, 90 insertions, 106 deletions
diff --git a/Source/JavaScriptCore/runtime/JSLock.h b/Source/JavaScriptCore/runtime/JSLock.h
index 4d0d17420..3002add64 100644
--- a/Source/JavaScriptCore/runtime/JSLock.h
+++ b/Source/JavaScriptCore/runtime/JSLock.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2005, 2008, 2009, 2014 Apple Inc. All rights reserved.
+ * Copyright (C) 2005, 2008, 2009 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -21,125 +21,109 @@
#ifndef JSLock_h
#define JSLock_h
-#include <mutex>
-#include <thread>
#include <wtf/Assertions.h>
-#include <wtf/Lock.h>
#include <wtf/Noncopyable.h>
#include <wtf/RefPtr.h>
-#include <wtf/ThreadSafeRefCounted.h>
-#include <wtf/WTFThreadData.h>
+#include <wtf/TCSpinLock.h>
+#include <wtf/Threading.h>
namespace JSC {
-// To make it safe to use JavaScript on multiple threads, it is
-// important to lock before doing anything that allocates a
-// JavaScript data structure or that interacts with shared state
-// such as the protect count hash table. The simplest way to lock
-// is to create a local JSLockHolder object in the scope where the lock
-// must be held and pass it the context that requires protection.
-// The lock is recursive so nesting is ok. The JSLock
-// object also acts as a convenience short-hand for running important
-// initialization routines.
-
-// To avoid deadlock, sometimes it is necessary to temporarily
-// release the lock. Since it is recursive you actually have to
-// release all locks held by your thread. This is safe to do if
-// you are executing code that doesn't require the lock, and you
-// reacquire the right number of locks at the end. You can do this
-// by constructing a locally scoped JSLock::DropAllLocks object. The
-// DropAllLocks object takes care to release the JSLock only if your
-// thread acquired it to begin with.
-
-class ExecState;
-class VM;
-
-// This class is used to protect the initialization of the legacy single
-// shared VM.
-class GlobalJSLock {
- WTF_MAKE_NONCOPYABLE(GlobalJSLock);
-public:
- JS_EXPORT_PRIVATE GlobalJSLock();
- JS_EXPORT_PRIVATE ~GlobalJSLock();
-private:
- static StaticLock s_sharedInstanceMutex;
-};
-
-class JSLockHolder {
-public:
- JS_EXPORT_PRIVATE JSLockHolder(VM*);
- JS_EXPORT_PRIVATE JSLockHolder(VM&);
- JS_EXPORT_PRIVATE JSLockHolder(ExecState*);
-
- JS_EXPORT_PRIVATE ~JSLockHolder();
-private:
- void init();
-
- RefPtr<VM> m_vm;
-};
-
-class JSLock : public ThreadSafeRefCounted<JSLock> {
- WTF_MAKE_NONCOPYABLE(JSLock);
-public:
- JSLock(VM*);
- JS_EXPORT_PRIVATE ~JSLock();
-
- JS_EXPORT_PRIVATE void lock();
- JS_EXPORT_PRIVATE void unlock();
-
- static void lock(ExecState*);
- static void unlock(ExecState*);
- static void lock(VM&);
- static void unlock(VM&);
-
- VM* vm() { return m_vm; }
-
- bool hasExclusiveThread() const { return m_hasExclusiveThread; }
- std::thread::id exclusiveThread() const
- {
- ASSERT(m_hasExclusiveThread);
- return m_ownerThreadID;
- }
- JS_EXPORT_PRIVATE void setExclusiveThread(std::thread::id);
- JS_EXPORT_PRIVATE bool currentThreadIsHoldingLock();
-
- void willDestroyVM(VM*);
-
- class DropAllLocks {
- WTF_MAKE_NONCOPYABLE(DropAllLocks);
+ // To make it safe to use JavaScript on multiple threads, it is
+ // important to lock before doing anything that allocates a
+ // JavaScript data structure or that interacts with shared state
+ // such as the protect count hash table. The simplest way to lock
+ // is to create a local JSLockHolder object in the scope where the lock
+ // must be held and pass it the context that requires protection.
+ // The lock is recursive so nesting is ok. The JSLock
+ // object also acts as a convenience short-hand for running important
+ // initialization routines.
+
+ // To avoid deadlock, sometimes it is necessary to temporarily
+ // release the lock. Since it is recursive you actually have to
+ // release all locks held by your thread. This is safe to do if
+ // you are executing code that doesn't require the lock, and you
+ // reacquire the right number of locks at the end. You can do this
+ // by constructing a locally scoped JSLock::DropAllLocks object. The
+ // DropAllLocks object takes care to release the JSLock only if your
+ // thread acquired it to begin with.
+
+ class ExecState;
+ class VM;
+
+ // This class is used to protect the initialization of the legacy single
+ // shared VM.
+ class GlobalJSLock {
+ WTF_MAKE_NONCOPYABLE(GlobalJSLock);
public:
- JS_EXPORT_PRIVATE DropAllLocks(ExecState*);
- JS_EXPORT_PRIVATE DropAllLocks(VM*);
- JS_EXPORT_PRIVATE DropAllLocks(VM&);
- JS_EXPORT_PRIVATE ~DropAllLocks();
-
- void setDropDepth(unsigned depth) { m_dropDepth = depth; }
- unsigned dropDepth() const { return m_dropDepth; }
+ JS_EXPORT_PRIVATE GlobalJSLock();
+ JS_EXPORT_PRIVATE ~GlobalJSLock();
+ static void initialize();
private:
- intptr_t m_droppedLockCount;
- RefPtr<VM> m_vm;
- unsigned m_dropDepth;
+ static Mutex* s_sharedInstanceLock;
};
-private:
- void lock(intptr_t lockCount);
- void unlock(intptr_t unlockCount);
+ class JSLockHolder {
+ public:
+ JS_EXPORT_PRIVATE JSLockHolder(VM*);
+ JS_EXPORT_PRIVATE JSLockHolder(VM&);
+ JS_EXPORT_PRIVATE JSLockHolder(ExecState*);
+
+ JS_EXPORT_PRIVATE ~JSLockHolder();
+ private:
+ void init();
- void didAcquireLock();
- void willReleaseLock();
+ RefPtr<VM> m_vm;
+ };
- unsigned dropAllLocks(DropAllLocks*);
- void grabAllLocks(DropAllLocks*, unsigned lockCount);
+ class JSLock : public ThreadSafeRefCounted<JSLock> {
+ WTF_MAKE_NONCOPYABLE(JSLock);
+ public:
+ JSLock(VM*);
+ JS_EXPORT_PRIVATE ~JSLock();
+
+ JS_EXPORT_PRIVATE void lock();
+ JS_EXPORT_PRIVATE void unlock();
+
+ static void lock(ExecState*);
+ static void unlock(ExecState*);
+ static void lock(VM&);
+ static void unlock(VM&);
+
+ VM* vm() { return m_vm; }
+
+ JS_EXPORT_PRIVATE bool currentThreadIsHoldingLock();
+
+ unsigned dropAllLocks(SpinLock&);
+ unsigned dropAllLocksUnconditionally(SpinLock&);
+ void grabAllLocks(unsigned lockCount, SpinLock&);
+
+ void willDestroyVM(VM*);
+
+ class DropAllLocks {
+ WTF_MAKE_NONCOPYABLE(DropAllLocks);
+ public:
+ // By default, we release all locks conditionally. Some clients, such as Mobile Safari,
+ // may require that we release all locks unconditionally.
+ enum AlwaysDropLocksTag { DontAlwaysDropLocks = 0, AlwaysDropLocks };
+ JS_EXPORT_PRIVATE DropAllLocks(ExecState*, AlwaysDropLocksTag = DontAlwaysDropLocks);
+ JS_EXPORT_PRIVATE DropAllLocks(VM*, AlwaysDropLocksTag = DontAlwaysDropLocks);
+ JS_EXPORT_PRIVATE ~DropAllLocks();
+
+ private:
+ intptr_t m_lockCount;
+ RefPtr<VM> m_vm;
+ };
- Lock m_lock;
- std::thread::id m_ownerThreadID;
- intptr_t m_lockCount;
- unsigned m_lockDropDepth;
- bool m_hasExclusiveThread;
- VM* m_vm;
- AtomicStringTable* m_entryAtomicStringTable;
-};
+ private:
+ SpinLock m_spinLock;
+ Mutex m_lock;
+ ThreadIdentifier m_ownerThread;
+ intptr_t m_lockCount;
+ unsigned m_lockDropDepth;
+ VM* m_vm;
+ };
} // namespace