18e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project/* 28e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. 3635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * Copyright (C) 2009 Google Inc. All rights reserved. 40bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * Copyright (C) 2009 Torch Mobile, Inc. All rights reserved. 58e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 68e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * Redistribution and use in source and binary forms, with or without 78e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * modification, are permitted provided that the following conditions 88e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * are met: 98e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 1. Redistributions of source code must retain the above copyright 118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * notice, this list of conditions and the following disclaimer. 128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright 138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * notice, this list of conditions and the following disclaimer in the 148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * documentation and/or other materials provided with the distribution. 158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * its contributors may be used to endorse or promote products derived 178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * from this software without specific prior written permission. 188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project */ 30635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 31635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project/* 32635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * There are numerous academic and practical works on how to implement pthread_cond_wait/pthread_cond_signal/pthread_cond_broadcast 33635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * functions on Win32. Here is one example: http://www.cs.wustl.edu/~schmidt/win32-cv-1.html which is widely credited as a 'starting point' 34635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * of modern attempts. There are several more or less proven implementations, one in Boost C++ library (http://www.boost.org) and another 35635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * in pthreads-win32 (http://sourceware.org/pthreads-win32/). 36635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * 37635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * The number of articles and discussions is the evidence of significant difficulties in implementing these primitives correctly. 38635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * The brief search of revisions, ChangeLog entries, discussions in comp.programming.threads and other places clearly documents 39635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * numerous pitfalls and performance problems the authors had to overcome to arrive to the suitable implementations. 40635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * Optimally, WebKit would use one of those supported/tested libraries directly. To roll out our own implementation is impractical, 41635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * if even for the lack of sufficient testing. However, a faithful reproduction of the code from one of the popular supported 42635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * libraries seems to be a good compromise. 43635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * 44635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * The early Boost implementation (http://www.boxbackup.org/trac/browser/box/nick/win/lib/win32/boost_1_32_0/libs/thread/src/condition.cpp?rev=30) 45635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * is identical to pthreads-win32 (http://sourceware.org/cgi-bin/cvsweb.cgi/pthreads/pthread_cond_wait.c?rev=1.10&content-type=text/x-cvsweb-markup&cvsroot=pthreads-win32). 46635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * Current Boost uses yet another (although seemingly equivalent) algorithm which came from their 'thread rewrite' effort. 478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 48635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * This file includes timedWait/signal/broadcast implementations translated to WebKit coding style from the latest algorithm by 49635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * Alexander Terekhov and Louis Thomas, as captured here: http://sourceware.org/cgi-bin/cvsweb.cgi/pthreads/pthread_cond_wait.c?rev=1.10&content-type=text/x-cvsweb-markup&cvsroot=pthreads-win32 50635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * It replaces the implementation of their previous algorithm, also documented in the same source above. 51635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * The naming and comments are left very close to original to enable easy cross-check. 528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 53635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * The corresponding Pthreads-win32 License is included below, and CONTRIBUTORS file which it refers to is added to 54635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * source directory (as CONTRIBUTORS.pthreads-win32). 55635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project */ 56635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 57635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project/* 58635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * Pthreads-win32 - POSIX Threads Library for Win32 59635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * Copyright(C) 1998 John E. Bossom 60635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * Copyright(C) 1999,2005 Pthreads-win32 contributors 618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 62635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * Contact Email: rpj@callisto.canberra.edu.au 638e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 64635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * The current list of contributors is contained 65635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * in the file CONTRIBUTORS included with the source 66635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * code distribution. The list can also be seen at the 67635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * following World Wide Web location: 68635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * http://sources.redhat.com/pthreads-win32/contributors.html 698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 70635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * This library is free software; you can redistribute it and/or 71635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * modify it under the terms of the GNU Lesser General Public 72635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * License as published by the Free Software Foundation; either 73635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * version 2 of the License, or (at your option) any later version. 748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project * 75635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * This library is distributed in the hope that it will be useful, 76635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * but WITHOUT ANY WARRANTY; without even the implied warranty of 77635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 78635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * Lesser General Public License for more details. 79635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * 80635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * You should have received a copy of the GNU Lesser General Public 81635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * License along with this library in the file COPYING.LIB; 82635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * if not, write to the Free Software Foundation, Inc., 83635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA 848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project */ 858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "config.h" 878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "Threading.h" 888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include "MainThread.h" 90cad810f21b803229eb11403f9209855525a25d57Steve Block#include "ThreadFunctionInvocation.h" 91cad810f21b803229eb11403f9209855525a25d57Steve Block#include <windows.h> 92cad810f21b803229eb11403f9209855525a25d57Steve Block#include <wtf/CurrentTime.h> 93cad810f21b803229eb11403f9209855525a25d57Steve Block#include <wtf/HashMap.h> 94cad810f21b803229eb11403f9209855525a25d57Steve Block#include <wtf/MathExtras.h> 95cad810f21b803229eb11403f9209855525a25d57Steve Block#include <wtf/OwnPtr.h> 96cad810f21b803229eb11403f9209855525a25d57Steve Block#include <wtf/PassOwnPtr.h> 97cad810f21b803229eb11403f9209855525a25d57Steve Block#include <wtf/RandomNumberSeed.h> 98cad810f21b803229eb11403f9209855525a25d57Steve Block 99d0825bca7fe65beaee391d30da42e937db621564Steve Block#if !USE(PTHREADS) && OS(WINDOWS) 100635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#include "ThreadSpecific.h" 101635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project#endif 102cad810f21b803229eb11403f9209855525a25d57Steve Block 103d0825bca7fe65beaee391d30da42e937db621564Steve Block#if !OS(WINCE) 1048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#include <process.h> 1050bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#endif 106cad810f21b803229eb11403f9209855525a25d57Steve Block 1070bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#if HAVE(ERRNO_H) 1080bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include <errno.h> 1090bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#endif 1108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectnamespace WTF { 1128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1138f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian// MS_VC_EXCEPTION, THREADNAME_INFO, and setThreadNameInternal all come from <http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx>. 1148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic const DWORD MS_VC_EXCEPTION = 0x406D1388; 1158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#pragma pack(push, 8) 1178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projecttypedef struct tagTHREADNAME_INFO { 1188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project DWORD dwType; // must be 0x1000 1198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LPCSTR szName; // pointer to name (in user addr space) 1208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project DWORD dwThreadID; // thread ID (-1=caller thread) 1218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project DWORD dwFlags; // reserved for future use, must be zero 1228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} THREADNAME_INFO; 1238e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#pragma pack(pop) 1248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 125d0825bca7fe65beaee391d30da42e937db621564Steve Blockvoid initializeCurrentThreadInternal(const char* szThreadName) 1268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project THREADNAME_INFO info; 1288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project info.dwType = 0x1000; 1298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project info.szName = szThreadName; 1308f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian info.dwThreadID = GetCurrentThreadId(); 1318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project info.dwFlags = 0; 1328e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project __try { 1348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project RaiseException(MS_VC_EXCEPTION, 0, sizeof(info)/sizeof(ULONG_PTR), reinterpret_cast<ULONG_PTR*>(&info)); 1358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } __except (EXCEPTION_CONTINUE_EXECUTION) { 1368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 1378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic Mutex* atomicallyInitializedStaticMutex; 1408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid lockAtomicallyInitializedStaticMutex() 1428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 143635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT(atomicallyInitializedStaticMutex); 1448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project atomicallyInitializedStaticMutex->lock(); 1458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1478e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid unlockAtomicallyInitializedStaticMutex() 1488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project atomicallyInitializedStaticMutex->unlock(); 1508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic Mutex& threadMapMutex() 1538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project static Mutex mutex; 1558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return mutex; 1568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid initializeThreading() 1598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 16021939df44de1705786c545cd1bf519d47250322dBen Murdoch if (atomicallyInitializedStaticMutex) 16121939df44de1705786c545cd1bf519d47250322dBen Murdoch return; 16221939df44de1705786c545cd1bf519d47250322dBen Murdoch 16321939df44de1705786c545cd1bf519d47250322dBen Murdoch atomicallyInitializedStaticMutex = new Mutex; 16421939df44de1705786c545cd1bf519d47250322dBen Murdoch threadMapMutex(); 16521939df44de1705786c545cd1bf519d47250322dBen Murdoch initializeRandomNumberGenerator(); 1668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1688e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic HashMap<DWORD, HANDLE>& threadMap() 1698e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project static HashMap<DWORD, HANDLE> map; 1718e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return map; 1728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1748e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic void storeThreadHandleByIdentifier(DWORD threadID, HANDLE threadHandle) 1758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project MutexLocker locker(threadMapMutex()); 177635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT(!threadMap().contains(threadID)); 1788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project threadMap().add(threadID, threadHandle); 1798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic HANDLE threadHandleForIdentifier(ThreadIdentifier id) 1828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project MutexLocker locker(threadMapMutex()); 1848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return threadMap().get(id); 1858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic void clearThreadHandleForIdentifier(ThreadIdentifier id) 1888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 1898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project MutexLocker locker(threadMapMutex()); 1908e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(threadMap().contains(id)); 1918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project threadMap().remove(id); 1928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 1938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 1948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectstatic unsigned __stdcall wtfThreadEntryPoint(void* param) 1958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 196cad810f21b803229eb11403f9209855525a25d57Steve Block OwnPtr<ThreadFunctionInvocation> invocation = adoptPtr(static_cast<ThreadFunctionInvocation*>(param)); 197cad810f21b803229eb11403f9209855525a25d57Steve Block void* result = invocation->function(invocation->data); 1988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 199d0825bca7fe65beaee391d30da42e937db621564Steve Block#if !USE(PTHREADS) && OS(WINDOWS) 200635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // Do the TLS cleanup. 201635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ThreadSpecificThreadExit(); 2028e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project#endif 2038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return reinterpret_cast<unsigned>(result); 2058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 207635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectThreadIdentifier createThreadInternal(ThreadFunction entryPoint, void* data, const char* threadName) 2088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2098e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project unsigned threadIdentifier = 0; 2108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ThreadIdentifier threadID = 0; 211cad810f21b803229eb11403f9209855525a25d57Steve Block OwnPtr<ThreadFunctionInvocation> invocation = adoptPtr(new ThreadFunctionInvocation(entryPoint, data)); 212d0825bca7fe65beaee391d30da42e937db621564Steve Block#if OS(WINCE) 2130bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // This is safe on WINCE, since CRT is in the core and innately multithreaded. 2140bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch // On desktop Windows, need to use _beginthreadex (not available on WinCE) if using any CRT functions 215cad810f21b803229eb11403f9209855525a25d57Steve Block HANDLE threadHandle = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)wtfThreadEntryPoint, invocation.get(), 0, (LPDWORD)&threadIdentifier); 2160bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#else 217cad810f21b803229eb11403f9209855525a25d57Steve Block HANDLE threadHandle = reinterpret_cast<HANDLE>(_beginthreadex(0, 0, wtfThreadEntryPoint, invocation.get(), 0, &threadIdentifier)); 2180bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#endif 2198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!threadHandle) { 220d0825bca7fe65beaee391d30da42e937db621564Steve Block#if OS(WINCE) 2210bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch LOG_ERROR("Failed to create thread at entry point %p with data %p: %ld", entryPoint, data, ::GetLastError()); 222cad810f21b803229eb11403f9209855525a25d57Steve Block#elif !HAVE(ERRNO_H) 2230bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch LOG_ERROR("Failed to create thread at entry point %p with data %p.", entryPoint, data); 2240bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#else 2258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOG_ERROR("Failed to create thread at entry point %p with data %p: %ld", entryPoint, data, errno); 2260bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#endif 2278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return 0; 2288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 2298e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 230cad810f21b803229eb11403f9209855525a25d57Steve Block // The thread will take ownership of invocation. 231cad810f21b803229eb11403f9209855525a25d57Steve Block invocation.leakPtr(); 232cad810f21b803229eb11403f9209855525a25d57Steve Block 2338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project threadID = static_cast<ThreadIdentifier>(threadIdentifier); 2348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project storeThreadHandleByIdentifier(threadIdentifier, threadHandle); 2358e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2368e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return threadID; 2378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2388e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2398e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectint waitForThreadCompletion(ThreadIdentifier threadID, void** result) 2408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2418e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(threadID); 2428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2438e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project HANDLE threadHandle = threadHandleForIdentifier(threadID); 2448e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (!threadHandle) 2458e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOG_ERROR("ThreadIdentifier %u did not correspond to an active thread when trying to quit", threadID); 2468e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 247635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DWORD joinResult = WaitForSingleObject(threadHandle, INFINITE); 2488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (joinResult == WAIT_FAILED) 2498e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project LOG_ERROR("ThreadIdentifier %u was found to be deadlocked trying to quit", threadID); 2508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 251635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CloseHandle(threadHandle); 2528e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project clearThreadHandleForIdentifier(threadID); 2538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2548e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return joinResult; 2558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2578e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid detachThread(ThreadIdentifier threadID) 2588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2598e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(threadID); 2605f1ab04193ad0130ca8204aadaceae083aca9881Feng Qian 2618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project HANDLE threadHandle = threadHandleForIdentifier(threadID); 2628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (threadHandle) 263635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CloseHandle(threadHandle); 2648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project clearThreadHandleForIdentifier(threadID); 2658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 267db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Blockvoid yield() 268db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block{ 269db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block ::Sleep(1); 270db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block} 271db14019a23d96bc8a444b6576a5da8bd1cfbc8b0Steve Block 2728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectThreadIdentifier currentThread() 2738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 274635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return static_cast<ThreadIdentifier>(GetCurrentThreadId()); 2758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2768e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectMutex::Mutex() 2788e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project m_mutex.m_recursionCount = 0; 280635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project InitializeCriticalSection(&m_mutex.m_internalMutex); 2818e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source ProjectMutex::~Mutex() 2848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 285635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DeleteCriticalSection(&m_mutex.m_internalMutex); 2868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2888e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid Mutex::lock() 2898e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 290635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project EnterCriticalSection(&m_mutex.m_internalMutex); 2918e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ++m_mutex.m_recursionCount; 2928e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 2938e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 2948e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectbool Mutex::tryLock() 2958e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 2968e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // This method is modeled after the behavior of pthread_mutex_trylock, 2978e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // which will return an error if the lock is already owned by the 2988e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // current thread. Since the primitive Win32 'TryEnterCriticalSection' 2998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // treats this as a successful case, it changes the behavior of several 3008e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // tests in WebKit that check to see if the current thread already 3018e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // owned this mutex (see e.g., IconDatabase::getOrCreateIconRecord) 302635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DWORD result = TryEnterCriticalSection(&m_mutex.m_internalMutex); 3038e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3048e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (result != 0) { // We got the lock 3058e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // If this thread already had the lock, we must unlock and 3068e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // return false so that we mimic the behavior of POSIX's 3078e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // pthread_mutex_trylock: 3088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project if (m_mutex.m_recursionCount > 0) { 309635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project LeaveCriticalSection(&m_mutex.m_internalMutex); 3108e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 3118e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3138e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ++m_mutex.m_recursionCount; 3148e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return true; 3158e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3168e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return false; 3188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3198e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 3208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Projectvoid Mutex::unlock() 3218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 3228e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project --m_mutex.m_recursionCount; 323635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project LeaveCriticalSection(&m_mutex.m_internalMutex); 3248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 326635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectbool PlatformCondition::timedWait(PlatformMutex& mutex, DWORD durationMilliseconds) 3278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 3288e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // Enter the wait state. 329635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DWORD res = WaitForSingleObject(m_blockLock, INFINITE); 3308e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(res == WAIT_OBJECT_0); 331635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ++m_waitersBlocked; 332635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project res = ReleaseSemaphore(m_blockLock, 1, 0); 3338e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(res); 3348e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 33581bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch --mutex.m_recursionCount; 336635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project LeaveCriticalSection(&mutex.m_internalMutex); 3378e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 338635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // Main wait - use timeout. 339635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project bool timedOut = (WaitForSingleObject(m_blockQueue, durationMilliseconds) == WAIT_TIMEOUT); 3408e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 341635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project res = WaitForSingleObject(m_unblockLock, INFINITE); 3428e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(res == WAIT_OBJECT_0); 343635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 344635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project int signalsLeft = m_waitersToUnblock; 345635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 346635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (m_waitersToUnblock) 347635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project --m_waitersToUnblock; 348635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project else if (++m_waitersGone == (INT_MAX / 2)) { // timeout/canceled or spurious semaphore 349635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project // timeout or spurious wakeup occured, normalize the m_waitersGone count 3508e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // this may occur if many calls to wait with a timeout are made and 3518e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project // no call to notify_* is made 352635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project res = WaitForSingleObject(m_blockLock, INFINITE); 3538e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(res == WAIT_OBJECT_0); 354635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_waitersBlocked -= m_waitersGone; 355635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project res = ReleaseSemaphore(m_blockLock, 1, 0); 3568e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(res); 357635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_waitersGone = 0; 3588e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 359635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 360635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project res = ReleaseMutex(m_unblockLock); 3618e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(res); 3628e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 363635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (signalsLeft == 1) { 364635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project res = ReleaseSemaphore(m_blockLock, 1, 0); // Open the gate. 3658e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(res); 3668e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3678e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 368635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project EnterCriticalSection (&mutex.m_internalMutex); 36981bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch ++mutex.m_recursionCount; 3708e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 371635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return !timedOut; 3728e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 3738e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 374635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid PlatformCondition::signal(bool unblockAll) 3758e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 376635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project unsigned signalsToIssue = 0; 3778e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 378635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project DWORD res = WaitForSingleObject(m_unblockLock, INFINITE); 3798e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(res == WAIT_OBJECT_0); 3808e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 381635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (m_waitersToUnblock) { // the gate is already closed 382635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!m_waitersBlocked) { // no-op 383635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project res = ReleaseMutex(m_unblockLock); 3848e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(res); 3858e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project return; 3868e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 3878e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 388635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (unblockAll) { 389635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project signalsToIssue = m_waitersBlocked; 390635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_waitersToUnblock += m_waitersBlocked; 391635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_waitersBlocked = 0; 392635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } else { 393635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project signalsToIssue = 1; 394635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ++m_waitersToUnblock; 395635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project --m_waitersBlocked; 396635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 397635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } else if (m_waitersBlocked > m_waitersGone) { 398635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project res = WaitForSingleObject(m_blockLock, INFINITE); // Close the gate. 3998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(res == WAIT_OBJECT_0); 400635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (m_waitersGone != 0) { 401635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_waitersBlocked -= m_waitersGone; 402635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_waitersGone = 0; 403635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 404635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (unblockAll) { 405635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project signalsToIssue = m_waitersBlocked; 406635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_waitersToUnblock = m_waitersBlocked; 407635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_waitersBlocked = 0; 4088e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } else { 409635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project signalsToIssue = 1; 410635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_waitersToUnblock = 1; 411635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project --m_waitersBlocked; 4128e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 413635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } else { // No-op. 414635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project res = ReleaseMutex(m_unblockLock); 415635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project ASSERT(res); 416635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return; 4178e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4188e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 419635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project res = ReleaseMutex(m_unblockLock); 4208e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(res); 4218e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 422635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (signalsToIssue) { 423635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project res = ReleaseSemaphore(m_blockQueue, signalsToIssue, 0); 4248e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project ASSERT(res); 4258e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project } 4268e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4278e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 428635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectstatic const long MaxSemaphoreCount = static_cast<long>(~0UL >> 1); 429635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 430635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectThreadCondition::ThreadCondition() 4318e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project{ 432635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_condition.m_waitersGone = 0; 433635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_condition.m_waitersBlocked = 0; 434635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_condition.m_waitersToUnblock = 0; 435635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_condition.m_blockLock = CreateSemaphore(0, 1, 1, 0); 436635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_condition.m_blockQueue = CreateSemaphore(0, 0, MaxSemaphoreCount, 0); 437635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_condition.m_unblockLock = CreateMutex(0, 0, 0); 438635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 439635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (!m_condition.m_blockLock || !m_condition.m_blockQueue || !m_condition.m_unblockLock) { 440635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (m_condition.m_blockLock) 441635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CloseHandle(m_condition.m_blockLock); 442635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (m_condition.m_blockQueue) 443635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CloseHandle(m_condition.m_blockQueue); 444635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project if (m_condition.m_unblockLock) 445635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CloseHandle(m_condition.m_unblockLock); 446635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project } 447635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} 4488e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 449635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source ProjectThreadCondition::~ThreadCondition() 450635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ 451635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CloseHandle(m_condition.m_blockLock); 452635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CloseHandle(m_condition.m_blockQueue); 453635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project CloseHandle(m_condition.m_unblockLock); 454635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} 4558e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 456635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid ThreadCondition::wait(Mutex& mutex) 457635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ 458635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_condition.timedWait(mutex.impl(), INFINITE); 459635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} 4608e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 461635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectbool ThreadCondition::timedWait(Mutex& mutex, double absoluteTime) 462635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ 4632fc2651226baac27029e38c9d6ef883fa32084dbSteve Block DWORD interval = absoluteTimeToWaitTimeoutInterval(absoluteTime); 4648e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4652fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (!interval) { 4662fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // Consider the wait to have timed out, even if our condition has already been signaled, to 4672fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // match the pthreads implementation. 468635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project return false; 4698f72e70a9fd78eec56623b3a62e68f16b7b27e28Feng Qian } 470635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 4712fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return m_condition.timedWait(mutex.impl(), interval); 472635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} 473635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 474635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid ThreadCondition::signal() 475635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ 476635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_condition.signal(false); // Unblock only 1 thread. 477635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project} 478635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project 479635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Projectvoid ThreadCondition::broadcast() 480635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project{ 481635860845790a19bf50bbc51ba8fb66a96dde068The Android Open Source Project m_condition.signal(true); // Unblock all threads. 4828e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} 4838e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project 4842fc2651226baac27029e38c9d6ef883fa32084dbSteve BlockDWORD absoluteTimeToWaitTimeoutInterval(double absoluteTime) 4852fc2651226baac27029e38c9d6ef883fa32084dbSteve Block{ 4862fc2651226baac27029e38c9d6ef883fa32084dbSteve Block double currentTime = WTF::currentTime(); 4872fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 4882fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // Time is in the past - return immediately. 4892fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (absoluteTime < currentTime) 4902fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return 0; 4912fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 4922fc2651226baac27029e38c9d6ef883fa32084dbSteve Block // Time is too far in the future (and would overflow unsigned long) - wait forever. 4932fc2651226baac27029e38c9d6ef883fa32084dbSteve Block if (absoluteTime - currentTime > static_cast<double>(INT_MAX) / 1000.0) 4942fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return INFINITE; 4952fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 4962fc2651226baac27029e38c9d6ef883fa32084dbSteve Block return static_cast<DWORD>((absoluteTime - currentTime) * 1000.0); 4972fc2651226baac27029e38c9d6ef883fa32084dbSteve Block} 4982fc2651226baac27029e38c9d6ef883fa32084dbSteve Block 4998e35f3cfc7fba1d1c829dc557ebad6409cbe16a2The Android Open Source Project} // namespace WTF 500