/*
* Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
* Copyright (C) 2009 Google Inc. All rights reserved.
+ * Copyright (C) 2009 Torch Mobile, Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
#include "Threading.h"
#include "MainThread.h"
-#if !USE(PTHREADS) && PLATFORM(WIN_OS)
+#if !USE(PTHREADS) && OS(WINDOWS)
#include "ThreadSpecific.h"
#endif
+#if !OS(WINCE)
#include <process.h>
+#endif
+#if HAVE(ERRNO_H)
+#include <errno.h>
+#else
+#define NO_ERRNO
+#endif
#include <windows.h>
#include <wtf/CurrentTime.h>
#include <wtf/HashMap.h>
namespace WTF {
-// MS_VC_EXCEPTION, THREADNAME_INFO, and setThreadName all come from <http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx>.
+// MS_VC_EXCEPTION, THREADNAME_INFO, and setThreadNameInternal all come from <http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx>.
static const DWORD MS_VC_EXCEPTION = 0x406D1388;
#pragma pack(push, 8)
} THREADNAME_INFO;
#pragma pack(pop)
-static void setThreadName(DWORD dwThreadID, LPCSTR szThreadName)
+void initializeCurrentThreadInternal(const char* szThreadName)
{
- // Visual Studio has a 31-character limit on thread names. Longer names will
- // be truncated silently, but we'd like callers to know about the limit.
- ASSERT_ARG(szThreadName, strlen(szThreadName) <= 31);
-
THREADNAME_INFO info;
info.dwType = 0x1000;
info.szName = szThreadName;
- info.dwThreadID = dwThreadID;
+ info.dwThreadID = GetCurrentThreadId();
info.dwFlags = 0;
__try {
atomicallyInitializedStaticMutex->unlock();
}
-static ThreadIdentifier mainThreadIdentifier;
-
static Mutex& threadMapMutex()
{
static Mutex mutex;
void initializeThreading()
{
- if (!atomicallyInitializedStaticMutex) {
- atomicallyInitializedStaticMutex = new Mutex;
- threadMapMutex();
- initializeRandomNumberGenerator();
- initializeMainThread();
- mainThreadIdentifier = currentThread();
- setThreadName(mainThreadIdentifier, "Main Thread");
- }
+ if (atomicallyInitializedStaticMutex)
+ return;
+
+ atomicallyInitializedStaticMutex = new Mutex;
+ threadMapMutex();
+ initializeRandomNumberGenerator();
}
static HashMap<DWORD, HANDLE>& threadMap()
void* result = invocation.function(invocation.data);
-#if !USE(PTHREADS) && PLATFORM(WIN_OS)
+#if !USE(PTHREADS) && OS(WINDOWS)
// Do the TLS cleanup.
ThreadSpecificThreadExit();
#endif
unsigned threadIdentifier = 0;
ThreadIdentifier threadID = 0;
ThreadFunctionInvocation* invocation = new ThreadFunctionInvocation(entryPoint, data);
+#if OS(WINCE)
+ // This is safe on WINCE, since CRT is in the core and innately multithreaded.
+ // On desktop Windows, need to use _beginthreadex (not available on WinCE) if using any CRT functions
+ HANDLE threadHandle = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)wtfThreadEntryPoint, invocation, 0, (LPDWORD)&threadIdentifier);
+#else
HANDLE threadHandle = reinterpret_cast<HANDLE>(_beginthreadex(0, 0, wtfThreadEntryPoint, invocation, 0, &threadIdentifier));
+#endif
if (!threadHandle) {
+#if OS(WINCE)
+ LOG_ERROR("Failed to create thread at entry point %p with data %p: %ld", entryPoint, data, ::GetLastError());
+#elif defined(NO_ERRNO)
+ LOG_ERROR("Failed to create thread at entry point %p with data %p.", entryPoint, data);
+#else
LOG_ERROR("Failed to create thread at entry point %p with data %p: %ld", entryPoint, data, errno);
+#endif
return 0;
}
- if (threadName)
- setThreadName(threadIdentifier, threadName);
-
threadID = static_cast<ThreadIdentifier>(threadIdentifier);
storeThreadHandleByIdentifier(threadIdentifier, threadHandle);
void detachThread(ThreadIdentifier threadID)
{
ASSERT(threadID);
-
+
HANDLE threadHandle = threadHandleForIdentifier(threadID);
if (threadHandle)
CloseHandle(threadHandle);
return static_cast<ThreadIdentifier>(GetCurrentThreadId());
}
-bool isMainThread()
-{
- return currentThread() == mainThreadIdentifier;
-}
-
Mutex::Mutex()
{
m_mutex.m_recursionCount = 0;
if (absoluteTime < currentTime)
return false;
- double intervalMilliseconds = (absoluteTime - currentTime) * 1000.0;
- if (intervalMilliseconds >= INT_MAX)
- intervalMilliseconds = INT_MAX;
+ // Time is too far in the future (and would overflow unsigned long) - wait forever.
+ if (absoluteTime - currentTime > static_cast<double>(INT_MAX) / 1000.0) {
+ wait(mutex);
+ return true;
+ }
+ double intervalMilliseconds = (absoluteTime - currentTime) * 1000.0;
return m_condition.timedWait(mutex.impl(), static_cast<unsigned long>(intervalMilliseconds));
}