15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2008 Apple Inc. All Rights Reserved.
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2009 Google Inc. All Rights Reserved.
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * are met:
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 1. Redistributions of source code must retain the above copyright
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *    notice, this list of conditions and the following disclaimer.
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 2. Redistributions in binary form must reproduce the above copyright
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *    notice, this list of conditions and the following disclaimer in the
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *    documentation and/or other materials provided with the distribution.
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */
275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h"
295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/workers/WorkerMessagingProxy.h"
3153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
3253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/CrossThreadTask.h"
3353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/Document.h"
3406f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)#include "core/events/ErrorEvent.h"
3506f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)#include "core/events/MessageEvent.h"
36e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)#include "core/frame/Console.h"
37e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)#include "core/frame/FrameConsole.h"
3876c265b59aa821ccbf8c75ab2bb0d036e97d2956Torne (Richard Coles)#include "core/frame/LocalDOMWindow.h"
39e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)#include "core/frame/LocalFrame.h"
40d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "core/frame/csp/ContentSecurityPolicy.h"
4153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/inspector/ScriptCallStack.h"
4253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/inspector/WorkerDebuggerAgent.h"
43521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)#include "core/loader/DocumentLoadTiming.h"
44521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)#include "core/loader/DocumentLoader.h"
45591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "core/workers/DedicatedWorkerGlobalScope.h"
4653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/workers/DedicatedWorkerThread.h"
4753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/workers/Worker.h"
487757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch#include "core/workers/WorkerClients.h"
499e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)#include "core/workers/WorkerInspectorProxy.h"
50a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "core/workers/WorkerObjectProxy.h"
517757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch#include "core/workers/WorkerThreadStartupData.h"
521e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/NotImplemented.h"
53f91f5fa1608c2cdd9af1842fb5dadbe78275be2aBo Liu#include "platform/heap/Handle.h"
5451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "wtf/Functional.h"
55e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)#include "wtf/MainThread.h"
565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
57c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
591e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)class MessageWorkerGlobalScopeTask : public ExecutionContextTask {
605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)public:
61591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    static PassOwnPtr<MessageWorkerGlobalScopeTask> create(PassRefPtr<SerializedScriptValue> message, PassOwnPtr<MessagePortChannelArray> channels)
625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
63591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        return adoptPtr(new MessageWorkerGlobalScopeTask(message, channels));
645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)private:
67591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    MessageWorkerGlobalScopeTask(PassRefPtr<SerializedScriptValue> message, PassOwnPtr<MessagePortChannelArray> channels)
685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        : m_message(message)
695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        , m_channels(channels)
705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
731e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    virtual void performTask(ExecutionContext* scriptContext)
745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    {
75591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        ASSERT_WITH_SECURITY_IMPLICATION(scriptContext->isWorkerGlobalScope());
76591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        DedicatedWorkerGlobalScope* context = static_cast<DedicatedWorkerGlobalScope*>(scriptContext);
77197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch        OwnPtrWillBeRawPtr<MessagePortArray> ports = MessagePort::entanglePorts(*scriptContext, m_channels.release());
785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        context->dispatchEvent(MessageEvent::create(ports.release(), m_message));
795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        context->thread()->workerObjectProxy().confirmMessageFromWorkerObject(context->hasPendingActivity());
805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)private:
835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RefPtr<SerializedScriptValue> m_message;
845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    OwnPtr<MessagePortChannelArray> m_channels;
855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)};
865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
876f543c786fc42989f552b4daa774ca5ff32fa697Ben MurdochWorkerMessagingProxy::WorkerMessagingProxy(Worker* workerObject, PassOwnPtrWillBeRawPtr<WorkerClients> workerClients)
881e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    : m_executionContext(workerObject->executionContext())
89a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    , m_workerObjectProxy(WorkerObjectProxy::create(m_executionContext.get(), this))
905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_workerObject(workerObject)
915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_mayBeDestroyed(false)
925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_unconfirmedMessageCount(0)
935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_workerThreadHadPendingActivity(false)
945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    , m_askedToTerminate(false)
959e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    , m_workerInspectorProxy(WorkerInspectorProxy::create())
967757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    , m_workerClients(workerClients)
975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(m_workerObject);
991e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    ASSERT((m_executionContext->isDocument() && isMainThread())
1001e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        || (m_executionContext->isWorkerGlobalScope() && toWorkerGlobalScope(m_executionContext.get())->thread()->isCurrentThread()));
1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)WorkerMessagingProxy::~WorkerMessagingProxy()
1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(!m_workerObject);
1061e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    ASSERT((m_executionContext->isDocument() && isMainThread())
1071e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        || (m_executionContext->isWorkerGlobalScope() && toWorkerGlobalScope(m_executionContext.get())->thread()->isCurrentThread()));
1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
110591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochvoid WorkerMessagingProxy::startWorkerGlobalScope(const KURL& scriptURL, const String& userAgent, const String& sourceCode, WorkerThreadStartMode startMode)
1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // FIXME: This need to be revisited when we support nested worker one day
1131e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    ASSERT(m_executionContext->isDocument());
1149e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    if (m_askedToTerminate) {
1159e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        // Worker.terminate() could be called from JS before the thread was created.
1169e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        return;
1179e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    }
1181e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    Document* document = toDocument(m_executionContext.get());
1197757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
120d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    OwnPtrWillBeRawPtr<WorkerThreadStartupData> startupData = WorkerThreadStartupData::create(scriptURL, userAgent, sourceCode, startMode, document->contentSecurityPolicy()->deprecatedHeader(), document->contentSecurityPolicy()->deprecatedHeaderType(), m_workerClients.release());
1217757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch    double originTime = document->loader() ? document->loader()->timing()->referenceMonotonicTime() : monotonicallyIncreasingTime();
1227757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch
123a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    RefPtr<DedicatedWorkerThread> thread = DedicatedWorkerThread::create(*this, *m_workerObjectProxy.get(), originTime, startupData.release());
1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    thread->start();
125c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    workerThreadCreated(thread);
1269e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    m_workerInspectorProxy->workerThreadCreated(m_executionContext.get(), m_workerThread.get(), scriptURL);
1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void WorkerMessagingProxy::postMessageToWorkerObject(PassRefPtr<SerializedScriptValue> message, PassOwnPtr<MessagePortChannelArray> channels)
1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
131a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    if (!m_workerObject || m_askedToTerminate)
132a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        return;
133a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)
134197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    OwnPtrWillBeRawPtr<MessagePortArray> ports = MessagePort::entanglePorts(*m_executionContext.get(), channels);
135a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    m_workerObject->dispatchEvent(MessageEvent::create(ports.release(), message));
1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
138591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochvoid WorkerMessagingProxy::postMessageToWorkerGlobalScope(PassRefPtr<SerializedScriptValue> message, PassOwnPtr<MessagePortChannelArray> channels)
1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_askedToTerminate)
1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_workerThread) {
1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ++m_unconfirmedMessageCount;
145c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)        m_workerThread->postTask(MessageWorkerGlobalScopeTask::create(message, channels));
1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    } else
147591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        m_queuedEarlyTasks.append(MessageWorkerGlobalScopeTask::create(message, channels));
1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
15009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)bool WorkerMessagingProxy::postTaskToWorkerGlobalScope(PassOwnPtr<ExecutionContextTask> task)
1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_askedToTerminate)
1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return false;
1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(m_workerThread);
156c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)    m_workerThread->postTask(task);
1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return true;
1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1601e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)void WorkerMessagingProxy::postTaskToLoader(PassOwnPtr<ExecutionContextTask> task)
1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // FIXME: In case of nested workers, this should go directly to the root Document context.
1631e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    ASSERT(m_executionContext->isDocument());
1641e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    m_executionContext->postTask(task);
1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
16751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)void WorkerMessagingProxy::reportException(const String& errorMessage, int lineNumber, int columnNumber, const String& sourceURL)
1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
169a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    if (!m_workerObject)
1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
171a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)
172a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    // We don't bother checking the askedToTerminate() flag here, because exceptions should *always* be reported even if the thread is terminated.
173a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    // This is intentionally different than the behavior in MessageWorkerTask, because terminated workers no longer deliver messages (section 4.6 of the WebWorker spec), but they do report exceptions.
174a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)
175a9984bf9ddc3cf73fdae3f29134a2bab379e7029Ben Murdoch    RefPtrWillBeRawPtr<ErrorEvent> event = ErrorEvent::create(errorMessage, sourceURL, lineNumber, columnNumber, 0);
176a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    bool errorHandled = !m_workerObject->dispatchEvent(event);
177a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    if (!errorHandled)
1787242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        m_executionContext->reportException(event, 0, nullptr, NotSharableCrossOrigin);
1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
18151b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)void WorkerMessagingProxy::reportConsoleMessage(MessageSource source, MessageLevel level, const String& message, int lineNumber, const String& sourceURL)
1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
183a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    if (m_askedToTerminate)
184a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)        return;
185e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    // FIXME: In case of nested workers, this should go directly to the root Document context.
186e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    ASSERT(m_executionContext->isDocument());
187e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    Document* document = toDocument(m_executionContext.get());
188e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    LocalFrame* frame = document->frame();
189e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    if (!frame)
190e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        return;
191e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)
192e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    RefPtrWillBeRawPtr<ConsoleMessage> consoleMessage = ConsoleMessage::create(source, level, message, sourceURL, lineNumber);
1937242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    consoleMessage->setWorkerGlobalScopeProxy(this);
194e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    frame->console().addMessage(consoleMessage.release());
1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void WorkerMessagingProxy::workerThreadCreated(PassRefPtr<DedicatedWorkerThread> workerThread)
1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1999e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    ASSERT(!m_askedToTerminate);
2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_workerThread = workerThread;
2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2029e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    unsigned taskCount = m_queuedEarlyTasks.size();
2039e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    ASSERT(!m_unconfirmedMessageCount);
2049e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    m_unconfirmedMessageCount = taskCount;
2059e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    m_workerThreadHadPendingActivity = true; // Worker initialization means a pending activity.
2069e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)
2079e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    for (unsigned i = 0; i < taskCount; ++i)
2089e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        m_workerThread->postTask(m_queuedEarlyTasks[i].release());
2099e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    m_queuedEarlyTasks.clear();
2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void WorkerMessagingProxy::workerObjectDestroyed()
2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_workerObject = 0;
215197021e6b966cfb06891637935ef33fff06433d1Ben Murdoch    m_executionContext->postTask(createCrossThreadTask(&workerObjectDestroyedInternal, AllowCrossThreadAccess(this)));
2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2181e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)void WorkerMessagingProxy::workerObjectDestroyedInternal(ExecutionContext*, WorkerMessagingProxy* proxy)
2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    proxy->m_mayBeDestroyed = true;
2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (proxy->m_workerThread)
222591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        proxy->terminateWorkerGlobalScope();
2235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    else
224e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)        proxy->workerThreadTerminated();
2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
227e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)void WorkerMessagingProxy::workerThreadTerminated()
2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
229a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    // This method is always the last to be performed, so the proxy is not needed for communication
2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // in either side any more. However, the Worker object may still exist, and it assumes that the proxy exists, too.
2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_askedToTerminate = true;
232d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    m_workerThread = nullptr;
233e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    terminateInternally();
2345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_mayBeDestroyed)
2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        delete this;
2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
238591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdochvoid WorkerMessagingProxy::terminateWorkerGlobalScope()
2395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_askedToTerminate)
2415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
2425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_askedToTerminate = true;
2435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (m_workerThread)
2455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        m_workerThread->stop();
2465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
247e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    terminateInternally();
2485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void WorkerMessagingProxy::postMessageToPageInspector(const String& message)
2515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2529e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    if (!m_workerInspectorProxy)
2539e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        return;
2549e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    WorkerInspectorProxy::PageInspector* pageInspector = m_workerInspectorProxy->pageInspector();
2559e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    if (pageInspector)
2569e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)        pageInspector->dispatchMessageFromWorker(message);
2579e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)}
2589e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)
2599e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)WorkerInspectorProxy* WorkerMessagingProxy::workerInspectorProxy()
2609e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles){
2619e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    return m_workerInspectorProxy.get();
2625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void WorkerMessagingProxy::confirmMessageFromWorkerObject(bool hasPendingActivity)
2655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
266a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    if (!m_askedToTerminate) {
2675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        ASSERT(m_unconfirmedMessageCount);
2685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        --m_unconfirmedMessageCount;
2695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
270a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)    reportPendingActivity(hasPendingActivity);
271a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)}
2725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
273a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)void WorkerMessagingProxy::reportPendingActivity(bool hasPendingActivity)
274a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles){
2755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_workerThreadHadPendingActivity = hasPendingActivity;
2765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
2785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool WorkerMessagingProxy::hasPendingActivity() const
2795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
2805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return (m_unconfirmedMessageCount || m_workerThreadHadPendingActivity) && !m_askedToTerminate;
2815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
2825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
283e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)void WorkerMessagingProxy::terminateInternally()
284e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles){
2859e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)    m_workerInspectorProxy->workerThreadTerminated();
286e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)
287e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    // FIXME: This need to be revisited when we support nested worker one day
288e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    ASSERT(m_executionContext->isDocument());
289e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    Document* document = toDocument(m_executionContext.get());
290e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    LocalFrame* frame = document->frame();
291e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)    if (frame)
2927242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        frame->console().adoptWorkerMessagesAfterTermination(this);
293e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)}
294e38fbeeb576b5094e34e038ab88d9d6a5c5c2214Torne (Richard Coles)
295c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink
296