15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. 35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2009 Google Inc. All rights reserved. 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2009 Torch Mobile, Inc. All rights reserved. 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without 75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * are met: 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 1. Redistributions of source code must retain the above copyright 1102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch * notice, this list of conditions and the following disclaimer. 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 2. Redistributions in binary form must reproduce the above copyright 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * notice, this list of conditions and the following disclaimer in the 1402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch * documentation and/or other materials provided with the distribution. 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * its contributors may be used to endorse or promote products derived 1702772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch * from this software without specific prior written permission. 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* 325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * There are numerous academic and practical works on how to implement pthread_cond_wait/pthread_cond_signal/pthread_cond_broadcast 335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 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' 345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * of modern attempts. There are several more or less proven implementations, one in Boost C++ library (http://www.boost.org) and another 355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * in pthreads-win32 (http://sourceware.org/pthreads-win32/). 365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * The number of articles and discussions is the evidence of significant difficulties in implementing these primitives correctly. 385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * The brief search of revisions, ChangeLog entries, discussions in comp.programming.threads and other places clearly documents 395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * numerous pitfalls and performance problems the authors had to overcome to arrive to the suitable implementations. 405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Optimally, WebKit would use one of those supported/tested libraries directly. To roll out our own implementation is impractical, 415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * if even for the lack of sufficient testing. However, a faithful reproduction of the code from one of the popular supported 425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * libraries seems to be a good compromise. 435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 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) 455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 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). 465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Current Boost uses yet another (although seemingly equivalent) algorithm which came from their 'thread rewrite' effort. 475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This file includes timedWait/signal/broadcast implementations translated to WebKit coding style from the latest algorithm by 495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 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 505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * It replaces the implementation of their previous algorithm, also documented in the same source above. 515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * The naming and comments are left very close to original to enable easy cross-check. 525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * The corresponding Pthreads-win32 License is included below, and CONTRIBUTORS file which it refers to is added to 545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * source directory (as CONTRIBUTORS.pthreads-win32). 555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* 585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Pthreads-win32 - POSIX Threads Library for Win32 595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright(C) 1998 John E. Bossom 605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright(C) 1999,2005 Pthreads-win32 contributors 615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Contact Email: rpj@callisto.canberra.edu.au 635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * The current list of contributors is contained 655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * in the file CONTRIBUTORS included with the source 665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * code distribution. The list can also be seen at the 675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * following World Wide Web location: 685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * http://sources.redhat.com/pthreads-win32/contributors.html 695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is free software; you can redistribute it and/or 715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modify it under the terms of the GNU Lesser General Public 725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * License as published by the Free Software Foundation; either 735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * version 2 of the License, or (at your option) any later version. 745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is distributed in the hope that it will be useful, 765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * but WITHOUT ANY WARRANTY; without even the implied warranty of 775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Lesser General Public License for more details. 795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * You should have received a copy of the GNU Lesser General Public 815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * License along with this library in the file COPYING.LIB; 825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * if not, write to the Free Software Foundation, Inc., 835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA 845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h" 875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "Threading.h" 88926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 898abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)#if OS(WIN) 90926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 91591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "wtf/CurrentTime.h" 92c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)#include "wtf/DateMath.h" 93591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "wtf/HashMap.h" 94c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)#include "wtf/MainThread.h" 95591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "wtf/MathExtras.h" 96591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "wtf/OwnPtr.h" 97591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "wtf/PassOwnPtr.h" 98c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)#include "wtf/ThreadFunctionInvocation.h" 99c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)#include "wtf/ThreadSpecific.h" 100c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)#include "wtf/ThreadingPrimitives.h" 101591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "wtf/WTFThreadData.h" 102c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)#include "wtf/dtoa.h" 103c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)#include "wtf/dtoa/cached-powers.h" 1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include <errno.h> 105f5e4ad553afbc08dd2e729bb77e937a9a94d5827Torne (Richard Coles)#include <process.h> 106c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)#include <windows.h> 1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace WTF { 1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// MS_VC_EXCEPTION, THREADNAME_INFO, and setThreadNameInternal all come from <http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx>. 1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static const DWORD MS_VC_EXCEPTION = 0x406D1388; 1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#pragma pack(push, 8) 1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)typedef struct tagTHREADNAME_INFO { 1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DWORD dwType; // must be 0x1000 1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LPCSTR szName; // pointer to name (in user addr space) 1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DWORD dwThreadID; // thread ID (-1=caller thread) 1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DWORD dwFlags; // reserved for future use, must be zero 1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} THREADNAME_INFO; 1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#pragma pack(pop) 1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static Mutex* atomicallyInitializedStaticMutex; 1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void lockAtomicallyInitializedStaticMutex() 1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(atomicallyInitializedStaticMutex); 1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) atomicallyInitializedStaticMutex->lock(); 1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void unlockAtomicallyInitializedStaticMutex() 1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) atomicallyInitializedStaticMutex->unlock(); 1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void initializeThreading() 1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 13793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) // This should only be called once. 13893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles) ASSERT(!atomicallyInitializedStaticMutex); 1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // StringImpl::empty() does not construct its static string in a threadsafe fashion, 1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // so ensure it has been initialized from here. 1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) StringImpl::empty(); 1432fb29a03d7c71253319f61b77edc6c1e3a8fc8e2Torne (Richard Coles) StringImpl::empty16Bit(); 1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) atomicallyInitializedStaticMutex = new Mutex; 1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) wtfThreadData(); 1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) s_dtoaP5Mutex = new Mutex; 1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) initializeDates(); 1482fb29a03d7c71253319f61b77edc6c1e3a8fc8e2Torne (Richard Coles) // Force initialization of static DoubleToStringConverter converter variable 1492fb29a03d7c71253319f61b77edc6c1e3a8fc8e2Torne (Richard Coles) // inside EcmaScriptConverter function while we are in single thread mode. 1502fb29a03d7c71253319f61b77edc6c1e3a8fc8e2Torne (Richard Coles) double_conversion::DoubleToStringConverter::EcmaScriptConverter(); 1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)ThreadIdentifier currentThread() 1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return static_cast<ThreadIdentifier>(GetCurrentThreadId()); 1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 158c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)MutexBase::MutexBase(bool recursive) 1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_mutex.m_recursionCount = 0; 1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) InitializeCriticalSection(&m_mutex.m_internalMutex); 1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 164c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)MutexBase::~MutexBase() 1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DeleteCriticalSection(&m_mutex.m_internalMutex); 1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 169c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)void MutexBase::lock() 1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EnterCriticalSection(&m_mutex.m_internalMutex); 1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ++m_mutex.m_recursionCount; 1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 17402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 175c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)void MutexBase::unlock() 176c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles){ 177c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) ASSERT(m_mutex.m_recursionCount); 178c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) --m_mutex.m_recursionCount; 179c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) LeaveCriticalSection(&m_mutex.m_internalMutex); 180c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} 181c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) 1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool Mutex::tryLock() 1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // This method is modeled after the behavior of pthread_mutex_trylock, 1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // which will return an error if the lock is already owned by the 1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // current thread. Since the primitive Win32 'TryEnterCriticalSection' 1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // treats this as a successful case, it changes the behavior of several 1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // tests in WebKit that check to see if the current thread already 1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // owned this mutex (see e.g., IconDatabase::getOrCreateIconRecord) 1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DWORD result = TryEnterCriticalSection(&m_mutex.m_internalMutex); 19102772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch 1925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (result != 0) { // We got the lock 193c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) // If this thread already had the lock, we must unlock and return 194c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) // false since this is a non-recursive mutex. This is to mimic the 195c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) // behavior of POSIX's pthread_mutex_trylock. We don't do this 196c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) // check in the lock method (presumably due to performance?). This 197c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) // means lock() will succeed even if the current thread has already 198c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) // entered the critical section. 1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_mutex.m_recursionCount > 0) { 2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LeaveCriticalSection(&m_mutex.m_internalMutex); 2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ++m_mutex.m_recursionCount; 2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return true; 2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 210c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)bool RecursiveMutex::tryLock() 2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 212c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) // CRITICAL_SECTION is recursive/reentrant so TryEnterCriticalSection will 213c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) // succeed if the current thread is already in the critical section. 214c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) DWORD result = TryEnterCriticalSection(&m_mutex.m_internalMutex); 215c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) if (result == 0) { // We didn't get the lock. 216c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) return false; 217c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) } 218c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) ++m_mutex.m_recursionCount; 219c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles) return true; 2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool PlatformCondition::timedWait(PlatformMutex& mutex, DWORD durationMilliseconds) 2235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Enter the wait state. 2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DWORD res = WaitForSingleObject(m_blockLock, INFINITE); 2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT_UNUSED(res, res == WAIT_OBJECT_0); 2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ++m_waitersBlocked; 2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) res = ReleaseSemaphore(m_blockLock, 1, 0); 2295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT_UNUSED(res, res); 2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) --mutex.m_recursionCount; 2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) LeaveCriticalSection(&mutex.m_internalMutex); 2335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Main wait - use timeout. 2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool timedOut = (WaitForSingleObject(m_blockQueue, durationMilliseconds) == WAIT_TIMEOUT); 2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) res = WaitForSingleObject(m_unblockLock, INFINITE); 2385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT_UNUSED(res, res == WAIT_OBJECT_0); 2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) int signalsLeft = m_waitersToUnblock; 2415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_waitersToUnblock) 2435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) --m_waitersToUnblock; 2445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (++m_waitersGone == (INT_MAX / 2)) { // timeout/canceled or spurious semaphore 2455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // timeout or spurious wakeup occured, normalize the m_waitersGone count 2465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // this may occur if many calls to wait with a timeout are made and 2475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // no call to notify_* is made 2485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) res = WaitForSingleObject(m_blockLock, INFINITE); 2495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT_UNUSED(res, res == WAIT_OBJECT_0); 2505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_waitersBlocked -= m_waitersGone; 2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) res = ReleaseSemaphore(m_blockLock, 1, 0); 2525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT_UNUSED(res, res); 2535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_waitersGone = 0; 2545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) res = ReleaseMutex(m_unblockLock); 2575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT_UNUSED(res, res); 2585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (signalsLeft == 1) { 2605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) res = ReleaseSemaphore(m_blockLock, 1, 0); // Open the gate. 2615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT_UNUSED(res, res); 2625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EnterCriticalSection (&mutex.m_internalMutex); 2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ++mutex.m_recursionCount; 2665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return !timedOut; 2685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void PlatformCondition::signal(bool unblockAll) 2715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 2725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) unsigned signalsToIssue = 0; 2735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DWORD res = WaitForSingleObject(m_unblockLock, INFINITE); 2755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT_UNUSED(res, res == WAIT_OBJECT_0); 2765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_waitersToUnblock) { // the gate is already closed 2785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!m_waitersBlocked) { // no-op 2795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) res = ReleaseMutex(m_unblockLock); 2805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT_UNUSED(res, res); 2815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 2825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (unblockAll) { 2855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) signalsToIssue = m_waitersBlocked; 2865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_waitersToUnblock += m_waitersBlocked; 2875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_waitersBlocked = 0; 2885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 2895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) signalsToIssue = 1; 2905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ++m_waitersToUnblock; 2915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) --m_waitersBlocked; 2925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else if (m_waitersBlocked > m_waitersGone) { 2945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) res = WaitForSingleObject(m_blockLock, INFINITE); // Close the gate. 2955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT_UNUSED(res, res == WAIT_OBJECT_0); 2965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_waitersGone != 0) { 2975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_waitersBlocked -= m_waitersGone; 2985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_waitersGone = 0; 2995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (unblockAll) { 3015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) signalsToIssue = m_waitersBlocked; 3025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_waitersToUnblock = m_waitersBlocked; 3035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_waitersBlocked = 0; 3045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { 3055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) signalsToIssue = 1; 3065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_waitersToUnblock = 1; 3075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) --m_waitersBlocked; 3085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else { // No-op. 3105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) res = ReleaseMutex(m_unblockLock); 3115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT_UNUSED(res, res); 3125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return; 3135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) res = ReleaseMutex(m_unblockLock); 3165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT_UNUSED(res, res); 3175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (signalsToIssue) { 3195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) res = ReleaseSemaphore(m_blockQueue, signalsToIssue, 0); 3205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT_UNUSED(res, res); 3215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static const long MaxSemaphoreCount = static_cast<long>(~0UL >> 1); 3255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)ThreadCondition::ThreadCondition() 3275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_condition.m_waitersGone = 0; 3295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_condition.m_waitersBlocked = 0; 3305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_condition.m_waitersToUnblock = 0; 3315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_condition.m_blockLock = CreateSemaphore(0, 1, 1, 0); 3325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_condition.m_blockQueue = CreateSemaphore(0, 0, MaxSemaphoreCount, 0); 3335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_condition.m_unblockLock = CreateMutex(0, 0, 0); 3345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!m_condition.m_blockLock || !m_condition.m_blockQueue || !m_condition.m_unblockLock) { 3365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_condition.m_blockLock) 3375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) CloseHandle(m_condition.m_blockLock); 3385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_condition.m_blockQueue) 3395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) CloseHandle(m_condition.m_blockQueue); 3405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (m_condition.m_unblockLock) 3415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) CloseHandle(m_condition.m_unblockLock); 3425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)ThreadCondition::~ThreadCondition() 3465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) CloseHandle(m_condition.m_blockLock); 3485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) CloseHandle(m_condition.m_blockQueue); 3495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) CloseHandle(m_condition.m_unblockLock); 3505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 352c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)void ThreadCondition::wait(MutexBase& mutex) 3535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_condition.timedWait(mutex.impl(), INFINITE); 3555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 357c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)bool ThreadCondition::timedWait(MutexBase& mutex, double absoluteTime) 3585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) DWORD interval = absoluteTimeToWaitTimeoutInterval(absoluteTime); 3605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!interval) { 3625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Consider the wait to have timed out, even if our condition has already been signaled, to 3635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // match the pthreads implementation. 3645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return false; 3655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 3665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_condition.timedWait(mutex.impl(), interval); 3685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void ThreadCondition::signal() 3715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_condition.signal(false); // Unblock only 1 thread. 3735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void ThreadCondition::broadcast() 3765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) m_condition.signal(true); // Unblock all threads. 3785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)DWORD absoluteTimeToWaitTimeoutInterval(double absoluteTime) 3815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 3825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) double currentTime = WTF::currentTime(); 3835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Time is in the past - return immediately. 3855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (absoluteTime < currentTime) 3865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 3875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Time is too far in the future (and would overflow unsigned long) - wait forever. 3895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (absoluteTime - currentTime > static_cast<double>(INT_MAX) / 1000.0) 3905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return INFINITE; 3915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return static_cast<DWORD>((absoluteTime - currentTime) * 1000.0); 3935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 3945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 3955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} // namespace WTF 396926b001d589ce2f10facb93dd4b87578ea35a855Torne (Richard Coles) 3978abfc5808a4e34d6e03867af8bc440dee641886fTorne (Richard Coles)#endif // OS(WIN) 398