#include "config.h"
#if ENABLE(WORKERS)
#include "WorkerThread.h"
#include "KURL.h"
#include "PlatformString.h"
#include "ScriptSourceCode.h"
#include "ScriptValue.h"
#include "Worker.h"
#include "WorkerContext.h"
#include "WorkerMessagingProxy.h"
#include "WorkerTask.h"
#include <utility>
#include <wtf/Noncopyable.h>
namespace WebCore {
struct WorkerThreadStartupData : Noncopyable {
public:
static std::auto_ptr<WorkerThreadStartupData> create(const KURL& scriptURL, const String& userAgent, const String& sourceCode)
{
return std::auto_ptr<WorkerThreadStartupData>(new WorkerThreadStartupData(scriptURL, userAgent, sourceCode));
}
KURL m_scriptURL;
String m_userAgent;
String m_sourceCode;
private:
WorkerThreadStartupData(const KURL& scriptURL, const String& userAgent, const String& sourceCode);
};
WorkerThreadStartupData::WorkerThreadStartupData(const KURL& scriptURL, const String& userAgent, const String& sourceCode)
: m_scriptURL(scriptURL.copy())
, m_userAgent(userAgent.copy())
, m_sourceCode(sourceCode.copy())
{
}
PassRefPtr<WorkerThread> WorkerThread::create(const KURL& scriptURL, const String& userAgent, const String& sourceCode, WorkerMessagingProxy* messagingProxy)
{
return adoptRef(new WorkerThread(scriptURL, userAgent, sourceCode, messagingProxy));
}
WorkerThread::WorkerThread(const KURL& scriptURL, const String& userAgent, const String& sourceCode, WorkerMessagingProxy* messagingProxy)
: m_threadID(0)
, m_messagingProxy(messagingProxy)
, m_startupData(WorkerThreadStartupData::create(scriptURL, userAgent, sourceCode))
{
}
WorkerThread::~WorkerThread()
{
}
bool WorkerThread::start()
{
MutexLocker lock(m_threadCreationMutex);
if (m_threadID)
return true;
m_threadID = createThread(WorkerThread::workerThreadStart, this, "WebCore::Worker");
return m_threadID;
}
void* WorkerThread::workerThreadStart(void* thread)
{
return static_cast<WorkerThread*>(thread)->workerThread();
}
void* WorkerThread::workerThread()
{
{
MutexLocker lock(m_threadCreationMutex);
m_workerContext = WorkerContext::create(m_startupData->m_scriptURL, m_startupData->m_userAgent, this);
if (m_runLoop.terminated()) {
m_workerContext->script()->forbidExecution();
}
}
WorkerScriptController* script = m_workerContext->script();
script->evaluate(ScriptSourceCode(m_startupData->m_sourceCode, m_startupData->m_scriptURL));
m_startupData.clear();
m_messagingProxy->confirmWorkerThreadMessage(m_workerContext->hasPendingActivity());
m_runLoop.run(m_workerContext.get());
ThreadIdentifier threadID = m_threadID;
m_workerContext->clearScript();
ASSERT(m_workerContext->hasOneRef());
m_workerContext = 0;
detachThread(threadID);
return 0;
}
void WorkerThread::stop()
{
MutexLocker lock(m_threadCreationMutex);
if (m_workerContext)
m_workerContext->script()->forbidExecution();
m_runLoop.terminate();
}
}
#endif // ENABLE(WORKERS)