void* WorkerThread::workerThread() { { MutexLocker lock(m_threadCreationMutex); m_workerContext = createWorkerContext(m_startupData->m_scriptURL, m_startupData->m_userAgent); if (m_runLoop.terminated()) { // The worker was terminated before the thread had a chance to run. Since the context didn't exist yet, // forbidExecution() couldn't be called from stop(). m_workerContext->script()->forbidExecution(); } } WorkerScriptController* script = m_workerContext->script(); script->evaluate(ScriptSourceCode(m_startupData->m_sourceCode, m_startupData->m_scriptURL)); // Free the startup data to cause its member variable deref's happen on the worker's thread (since // all ref/derefs of these objects are happening on the thread at this point). Note that // WorkerThread::~WorkerThread happens on a different thread where it was created. m_startupData.clear(); runEventLoop(); ThreadIdentifier threadID = m_threadID; ASSERT(m_workerContext->hasOneRef()); // The below assignment will destroy the context, which will in turn notify messaging proxy. // We cannot let any objects survive past thread exit, because no other thread will run GC or otherwise destroy them. m_workerContext = 0; // The thread object may be already destroyed from notification now, don't try to access "this". detachThread(threadID); return 0; }
void executeScriptInWorker(WorkerThread* worker, WebWaitableEvent* waitEvent) { WorkerScriptController* scriptController = worker->workerGlobalScope()->script(); bool evaluateResult = scriptController->evaluate(ScriptSourceCode("var counter = 0; ++counter;")); ASSERT_UNUSED(evaluateResult, evaluateResult); waitEvent->signal(); }
void WorkerThread::workerThread() { // Propagate the mainThread's fenv to workers. #if PLATFORM(IOS) FloatingPointEnvironment::singleton().propagateMainThreadEnvironment(); #endif #if PLATFORM(GTK) GRefPtr<GMainContext> mainContext = adoptGRef(g_main_context_new()); g_main_context_push_thread_default(mainContext.get()); #endif { LockHolder lock(m_threadCreationMutex); m_workerGlobalScope = createWorkerGlobalScope(m_startupData->m_scriptURL, m_startupData->m_userAgent, m_startupData->m_contentSecurityPolicyResponseHeaders, m_startupData->m_shouldBypassMainWorldContentSecurityPolicy, WTFMove(m_startupData->m_topOrigin)); if (m_runLoop.terminated()) { // The worker was terminated before the thread had a chance to run. Since the context didn't exist yet, // forbidExecution() couldn't be called from stop(). m_workerGlobalScope->script()->forbidExecution(); } } WorkerScriptController* script = m_workerGlobalScope->script(); script->evaluate(ScriptSourceCode(m_startupData->m_sourceCode, m_startupData->m_scriptURL)); // Free the startup data to cause its member variable deref's happen on the worker's thread (since // all ref/derefs of these objects are happening on the thread at this point). Note that // WorkerThread::~WorkerThread happens on a different thread where it was created. m_startupData = nullptr; runEventLoop(); #if PLATFORM(GTK) g_main_context_pop_thread_default(mainContext.get()); #endif ThreadIdentifier threadID = m_threadID; ASSERT(m_workerGlobalScope->hasOneRef()); // The below assignment will destroy the context, which will in turn notify messaging proxy. // We cannot let any objects survive past thread exit, because no other thread will run GC or otherwise destroy them. m_workerGlobalScope = nullptr; // Clean up WebCore::ThreadGlobalData before WTF::WTFThreadData goes away! threadGlobalData().destroy(); // The thread object may be already destroyed from notification now, don't try to access "this". detachThread(threadID); }
void ScheduledAction::execute(WorkerContext* workerContext) { // In a Worker, the execution should always happen on a worker thread. ASSERT(workerContext->thread()->threadID() == currentThread()); WorkerScriptController* scriptController = workerContext->script(); if (m_function) { JSWorkerContext* contextWrapper = scriptController->workerContextWrapper(); executeFunctionInContext(contextWrapper, contextWrapper, workerContext); } else { ScriptSourceCode code(m_code, workerContext->url()); scriptController->evaluate(code); } }
void ScheduledAction::execute(WorkerContext* workerContext) { // In a Worker, the execution should always happen on a worker thread. ASSERT(workerContext->thread()->threadID() == currentThread()); WorkerScriptController* scriptController = workerContext->script(); if (!m_function.IsEmpty() && m_function->IsFunction()) { v8::HandleScope handleScope; v8::Handle<v8::Context> v8Context = v8::Local<v8::Context>::New(m_context.get()); ASSERT(!v8Context.IsEmpty()); v8::Context::Scope scope(v8Context); m_function->Call(v8Context->Global(), m_argc, m_argv); } else scriptController->evaluate(m_code); }
void WorkerThread::workerThread() { // Propagate the mainThread's fenv to workers. #if PLATFORM(IOS) fesetenv(&mainThreadFEnv); #endif { MutexLocker lock(m_threadCreationMutex); m_workerGlobalScope = createWorkerGlobalScope(m_startupData->m_scriptURL, m_startupData->m_userAgent, std::move(m_startupData->m_groupSettings), m_startupData->m_contentSecurityPolicy, m_startupData->m_contentSecurityPolicyType, m_startupData->m_topOrigin.release()); if (m_runLoop.terminated()) { // The worker was terminated before the thread had a chance to run. Since the context didn't exist yet, // forbidExecution() couldn't be called from stop(). m_workerGlobalScope->script()->forbidExecution(); } } WorkerScriptController* script = m_workerGlobalScope->script(); #if ENABLE(INSPECTOR) InspectorInstrumentation::willEvaluateWorkerScript(workerGlobalScope(), m_startupData->m_startMode); #endif script->evaluate(ScriptSourceCode(m_startupData->m_sourceCode, m_startupData->m_scriptURL)); // Free the startup data to cause its member variable deref's happen on the worker's thread (since // all ref/derefs of these objects are happening on the thread at this point). Note that // WorkerThread::~WorkerThread happens on a different thread where it was created. m_startupData.clear(); runEventLoop(); ThreadIdentifier threadID = m_threadID; ASSERT(m_workerGlobalScope->hasOneRef()); // The below assignment will destroy the context, which will in turn notify messaging proxy. // We cannot let any objects survive past thread exit, because no other thread will run GC or otherwise destroy them. m_workerGlobalScope = 0; // Clean up WebCore::ThreadGlobalData before WTF::WTFThreadData goes away! threadGlobalData().destroy(); // The thread object may be already destroyed from notification now, don't try to access "this". detachThread(threadID); }