Changeset 30522 in webkit for trunk/JavaScriptCore/wtf/ThreadingWin.cpp
- Timestamp:
- Feb 23, 2008, 11:50:04 AM (17 years ago)
- File:
-
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/wtf/ThreadingWin.cpp
r30421 r30522 28 28 29 29 #include "config.h" 30 #include "Logging.h"31 #include "Page.h"32 30 #include "Threading.h" 33 #include <errno.h> 31 34 32 #include <windows.h> 35 33 #include <wtf/HashMap.h> 36 34 37 namespace WebCore { 38 39 struct FunctionWithContext { 40 MainThreadFunction* function; 41 void* context; 42 FunctionWithContext(MainThreadFunction* f = 0, void* c = 0) : function(f), context(c) { } 43 }; 44 45 typedef Vector<FunctionWithContext> FunctionQueue; 46 47 static HWND threadingWindowHandle = 0; 48 static UINT threadingFiredMessage = 0; 49 const LPCWSTR kThreadingWindowClassName = L"ThreadingWindowClass"; 50 static bool processingCustomThreadingMessage = false; 35 namespace WTF { 51 36 52 37 static Mutex& threadMapMutex() … … 95 80 storeThreadHandleByIdentifier(threadIdentifier, threadHandle); 96 81 97 LOG(Threading, "Created thread with thread id %u", threadID);98 82 return threadID; 99 83 } … … 132 116 } 133 117 134 static Mutex& functionQueueMutex()118 Mutex::Mutex() 135 119 { 136 static Mutex staticFunctionQueueMutex;137 return staticFunctionQueueMutex;120 m_mutex.m_recursionCount = 0; 121 ::InitializeCriticalSection(&m_mutex.m_internalMutex); 138 122 } 139 123 140 static FunctionQueue& functionQueue()124 Mutex::~Mutex() 141 125 { 142 static FunctionQueue staticFunctionQueue; 143 return staticFunctionQueue; 126 ::DeleteCriticalSection(&m_mutex.m_internalMutex); 144 127 } 145 128 146 static void callFunctionsOnMainThread()129 void Mutex::lock() 147 130 { 148 FunctionQueue queueCopy; 149 { 150 MutexLocker locker(functionQueueMutex()); 151 queueCopy.swap(functionQueue()); 131 ::EnterCriticalSection(&m_mutex.m_internalMutex); 132 ++m_mutex.m_recursionCount; 133 } 134 135 bool Mutex::tryLock() 136 { 137 // This method is modeled after the behavior of pthread_mutex_trylock, 138 // which will return an error if the lock is already owned by the 139 // current thread. Since the primitive Win32 'TryEnterCriticalSection' 140 // treats this as a successful case, it changes the behavior of several 141 // tests in WebKit that check to see if the current thread already 142 // owned this mutex (see e.g., IconDatabase::getOrCreateIconRecord) 143 DWORD result = ::TryEnterCriticalSection(&m_mutex.m_internalMutex); 144 145 if (result != 0) { // We got the lock 146 // If this thread already had the lock, we must unlock and 147 // return false so that we mimic the behavior of POSIX's 148 // pthread_mutex_trylock: 149 if (m_mutex.m_recursionCount > 0) { 150 ::LeaveCriticalSection(&m_mutex.m_internalMutex); 151 return false; 152 } 153 154 ++m_mutex.m_recursionCount; 155 return true; 152 156 } 153 157 154 LOG(Threading, "Calling %u functions on the main thread", queueCopy.size()); 155 for (unsigned i = 0; i < queueCopy.size(); ++i) 156 queueCopy[i].function(queueCopy[i].context); 158 return false; 157 159 } 158 160 159 LRESULT CALLBACK ThreadingWindowWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)161 void Mutex::unlock() 160 162 { 161 if (message == threadingFiredMessage) { 162 processingCustomThreadingMessage = true; 163 callFunctionsOnMainThread(); 164 processingCustomThreadingMessage = false; 165 } else 166 return DefWindowProc(hWnd, message, wParam, lParam); 167 return 0; 163 --m_mutex.m_recursionCount; 164 ::LeaveCriticalSection(&m_mutex.m_internalMutex); 168 165 } 169 166 170 void initializeThreading() 171 { 172 if (threadingWindowHandle) 173 return; 174 175 WNDCLASSEX wcex; 176 memset(&wcex, 0, sizeof(WNDCLASSEX)); 177 wcex.cbSize = sizeof(WNDCLASSEX); 178 wcex.lpfnWndProc = ThreadingWindowWndProc; 179 wcex.hInstance = Page::instanceHandle(); 180 wcex.lpszClassName = kThreadingWindowClassName; 181 RegisterClassEx(&wcex); 182 183 threadingWindowHandle = CreateWindow(kThreadingWindowClassName, 0, 0, 184 CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, HWND_MESSAGE, 0, Page::instanceHandle(), 0); 185 threadingFiredMessage = RegisterWindowMessage(L"com.apple.WebKit.MainThreadFired"); 186 } 187 188 void callOnMainThread(MainThreadFunction* function, void* context) 189 { 190 ASSERT(function); 191 ASSERT(threadingWindowHandle); 192 193 if (processingCustomThreadingMessage) 194 LOG(Threading, "callOnMainThread() called recursively. Beware of nested PostMessage()s"); 195 196 { 197 MutexLocker locker(functionQueueMutex()); 198 functionQueue().append(FunctionWithContext(function, context)); 199 } 200 201 PostMessage(threadingWindowHandle, threadingFiredMessage, 0, 0); 202 } 203 204 } // namespace WebCore 167 } // namespace WTF
Note:
See TracChangeset
for help on using the changeset viewer.