Changeset 20104 in webkit for trunk/JavaScriptCore/kjs
- Timestamp:
- Mar 11, 2007, 4:57:11 PM (18 years ago)
- Location:
- trunk/JavaScriptCore/kjs
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/kjs/JSLock.cpp
r13089 r20104 30 30 #if USE(MULTIPLE_THREADS) 31 31 32 static pthread_once_t interpreterLockOnce = PTHREAD_ONCE_INIT; 33 static pthread_mutex_t interpreterLock; 34 static int interpreterLockCount = 0; 32 // Acquire this mutex before accessing lock-related data. 33 static pthread_mutex_t JSMutex = PTHREAD_MUTEX_INITIALIZER; 35 34 36 static void initializeJSLock() 35 // Thread-specific key that tells whether a thread holds the JSMutex. 36 pthread_key_t didLockJSMutex; 37 38 // Lock nesting count. 39 static int JSLockCount; 40 41 static void createDidLockJSMutex() 37 42 { 38 pthread_mutexattr_t attr; 39 40 pthread_mutexattr_init(&attr); 41 pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE); 42 43 pthread_mutex_init(&interpreterLock, &attr); 43 pthread_key_create(&didLockJSMutex, 0); 44 44 } 45 pthread_once_t createDidLockJSMutexOnce = PTHREAD_ONCE_INIT; 45 46 46 47 void JSLock::lock() 47 48 { 48 pthread_once(&interpreterLockOnce, initializeJSLock); 49 pthread_mutex_lock(&interpreterLock); 50 interpreterLockCount++; 51 Collector::registerThread(); 49 pthread_once(&createDidLockJSMutexOnce, createDidLockJSMutex); 50 51 if (!pthread_getspecific(didLockJSMutex)) { 52 pthread_mutex_lock(&JSMutex); 53 pthread_setspecific(didLockJSMutex, &didLockJSMutex); 54 } 55 ++JSLockCount; 56 57 Collector::registerThread(); 52 58 } 53 59 54 60 void JSLock::unlock() 55 61 { 56 interpreterLockCount--; 57 pthread_mutex_unlock(&interpreterLock); 62 ASSERT(JSLockCount); 63 ASSERT(!!pthread_getspecific(didLockJSMutex)); 64 65 --JSLockCount; 66 if (!JSLockCount) { 67 pthread_setspecific(didLockJSMutex, 0); 68 pthread_mutex_unlock(&JSMutex); 69 } 70 } 71 72 JSLock::DropAllLocks::DropAllLocks() 73 : m_lockCount(0) 74 { 75 pthread_once(&createDidLockJSMutexOnce, createDidLockJSMutex); 76 77 m_lockCount = !!pthread_getspecific(didLockJSMutex) ? JSLock::lockCount() : 0; 78 for (int i = 0; i < m_lockCount; i++) 79 JSLock::unlock(); 80 } 81 82 JSLock::DropAllLocks::~DropAllLocks() 83 { 84 for (int i = 0; i < m_lockCount; i++) 85 JSLock::lock(); 86 m_lockCount = 0; 58 87 } 59 88 … … 62 91 // If threading support is off, set the lock count to a constant value of 1 so assertions 63 92 // that the lock is held don't fail 64 const int interpreterLockCount = 1;93 const int JSLockCount = 1; 65 94 66 95 void JSLock::lock() … … 72 101 } 73 102 74 #endif75 76 int JSLock::lockCount()77 {78 return interpreterLockCount;79 }80 81 103 JSLock::DropAllLocks::DropAllLocks() 82 104 { 83 int lockCount = JSLock::lockCount();84 for (int i = 0; i < lockCount; i++) {85 JSLock::unlock();86 }87 m_lockCount = lockCount;88 105 } 89 106 90 107 JSLock::DropAllLocks::~DropAllLocks() 91 108 { 92 int lockCount = m_lockCount; 93 for (int i = 0; i < lockCount; i++) { 94 JSLock::lock(); 95 } 109 } 110 111 #endif // USE(MULTIPLE_THREADS) 112 113 int JSLock::lockCount() 114 { 115 return JSLockCount; 96 116 } 97 117 -
trunk/JavaScriptCore/kjs/JSLock.h
r12301 r20104 24 24 #define KJS_INTERPRETER_LOCK_H 25 25 26 #include <wtf/Assertions.h> 27 #include <wtf/Noncopyable.h> 28 26 29 namespace KJS { 27 30 28 // to make it safe to use JavaScript on multiple threads, it is31 // To make it safe to use JavaScript on multiple threads, it is 29 32 // important to lock before doing anything that allocates a 30 33 // garbage-collected object or which may affect other shared state … … 34 37 // is ok. 35 38 36 // Sometimes it is necessary to temporarily release the lock - 37 // since it is recursive you have to actually release all locks 38 // held by your thread. This is safe to do if you are executing 39 // code that doesn't require the lock, and reacquire the right 40 // number of locks at the end. You can do this by constructing a 41 // locally scoped JSLock::DropAllLocks object. 39 // To avoid deadlock, sometimes it is necessary to temporarily 40 // release the lock. Since it is recursive you actually have to 41 // release all locks held by your thread. This is safe to do if 42 // you are executing code that doesn't require the lock, and you 43 // reacquire the right number of locks at the end. You can do this 44 // by constructing a locally scoped JSLock::DropAllLocks object. The 45 // DropAllLocks object takes care to release the JSLock only if your 46 // thread acquired it to begin with. 42 47 43 class JSLock 44 { 48 class JSLock : Noncopyable { 45 49 public: 46 50 JSLock() … … 48 52 lock(); 49 53 } 50 ~JSLock() { 54 55 ~JSLock() 56 { 51 57 unlock(); 52 58 } … … 55 61 static void unlock(); 56 62 static int lockCount(); 57 58 class DropAllLocks {63 64 class DropAllLocks : Noncopyable { 59 65 public: 60 66 DropAllLocks(); 61 67 ~DropAllLocks(); 68 62 69 private: 63 70 int m_lockCount; 64 65 DropAllLocks(const DropAllLocks&);66 DropAllLocks& operator=(const DropAllLocks&);67 71 }; 68 69 private:70 JSLock(const JSLock&);71 JSLock& operator=(const JSLock&);72 72 }; 73 73
Note:
See TracChangeset
for help on using the changeset viewer.