#include "config.h"
#include "Threading.h"
#include <string.h>
namespace WTF {
struct NewThreadContext {
WTF_MAKE_FAST_ALLOCATED;
public:
NewThreadContext(ThreadFunction entryPoint, void* data, const char* name)
: entryPoint(entryPoint)
, data(data)
, name(name)
{
}
ThreadFunction entryPoint;
void* data;
const char* name;
Mutex creationMutex;
};
static void threadEntryPoint(void* contextData)
{
NewThreadContext* context = reinterpret_cast<NewThreadContext*>(contextData);
{
MutexLocker locker(context->creationMutex);
}
initializeCurrentThreadInternal(context->name);
ThreadFunction entryPoint = context->entryPoint;
void* data = context->data;
delete context;
entryPoint(data);
}
ThreadIdentifier createThread(ThreadFunction entryPoint, void* data, const char* name)
{
#if !LOG_DISABLED && PLATFORM(WIN)
if (name && strlen(name) > 31)
LOG_ERROR("Thread name \"%s\" is longer than 31 characters and will be truncated by Visual Studio", name);
#endif
NewThreadContext* context = new NewThreadContext(entryPoint, data, name);
MutexLocker locker(context->creationMutex);
return createThreadInternal(threadEntryPoint, context, name);
}
void setCurrentThreadIsUserInteractive()
{
#if HAVE(QOS_CLASSES)
pthread_set_qos_class_self_np(QOS_CLASS_USER_INTERACTIVE, 0);
#endif
}
void setCurrentThreadIsUserInitiated()
{
#if HAVE(QOS_CLASSES)
pthread_set_qos_class_self_np(QOS_CLASS_USER_INITIATED, 0);
#endif
}
#if PLATFORM(MAC) || PLATFORM(WIN)
typedef void* (*ThreadFunctionWithReturnValue)(void* argument);
WTF_EXPORT_PRIVATE ThreadIdentifier createThread(ThreadFunctionWithReturnValue entryPoint, void* data, const char* name);
struct ThreadFunctionWithReturnValueInvocation {
ThreadFunctionWithReturnValueInvocation(ThreadFunctionWithReturnValue function, void* data)
: function(function)
, data(data)
{
}
ThreadFunctionWithReturnValue function;
void* data;
};
static void compatEntryPoint(void* param)
{
auto invocation = std::unique_ptr<ThreadFunctionWithReturnValueInvocation>(static_cast<ThreadFunctionWithReturnValueInvocation*>(param));
invocation->function(invocation->data);
}
ThreadIdentifier createThread(ThreadFunctionWithReturnValue entryPoint, void* data, const char* name)
{
auto invocation = std::make_unique<ThreadFunctionWithReturnValueInvocation>(entryPoint, data);
return createThread(compatEntryPoint, invocation.release(), name);
}
WTF_EXPORT_PRIVATE int waitForThreadCompletion(ThreadIdentifier, void**);
int waitForThreadCompletion(ThreadIdentifier threadID, void**)
{
return waitForThreadCompletion(threadID);
}
WTF_EXPORT_PRIVATE ThreadIdentifier createThread(ThreadFunctionWithReturnValue entryPoint, void* data);
ThreadIdentifier createThread(ThreadFunctionWithReturnValue entryPoint, void* data)
{
auto invocation = std::make_unique<ThreadFunctionWithReturnValueInvocation>(entryPoint, data);
return createThread(compatEntryPoint, invocation.release(), 0);
}
#endif
}