15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2008, 2010 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
2402772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch * 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"
2953e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/workers/Worker.h"
3053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)
317757ec2eadfa2dd8ac2aeed0a4399e9b07ec38cbBen Murdoch#include "bindings/v8/ExceptionState.h"
3253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/dom/Document.h"
3306f816c7c76bc45a15e452ade8a34e8af077693eTorne (Richard Coles)#include "core/events/MessageEvent.h"
34e1f1df5f01594c0e62e751e4b46e779b85c2faa5Torne (Richard Coles)#include "core/fetch/ResourceFetcher.h"
3553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/inspector/InspectorInstrumentation.h"
361e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "core/frame/DOMWindow.h"
3751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "core/frame/UseCounter.h"
38591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch#include "core/workers/WorkerGlobalScopeProxy.h"
3951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)#include "core/workers/WorkerGlobalScopeProxyProvider.h"
4053e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/workers/WorkerScriptLoader.h"
4153e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/workers/WorkerThread.h"
4281a5157921f1d2a7ff6aae115bfe3c139b38a5c8Torne (Richard Coles)#include "wtf/MainThread.h"
435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace WebCore {
455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
461e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)inline Worker::Worker(ExecutionContext* context)
475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    : AbstractWorker(context)
4851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    , m_contextProxy(0)
495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
50e52495584422c5edb5b2944981473a2e208da323Torne (Richard Coles)    ScriptWrappable::init(this);
515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
5351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)PassRefPtr<Worker> Worker::create(ExecutionContext* context, const String& url, ExceptionState& exceptionState)
545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(isMainThread());
5651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    Document* document = toDocument(context);
5751b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    UseCounter::count(document->domWindow(), UseCounter::WorkerStart);
5851b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    ASSERT(document->page());
5951b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    WorkerGlobalScopeProxyProvider* proxyProvider = WorkerGlobalScopeProxyProvider::from(document->page());
6051b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    ASSERT(proxyProvider);
615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    RefPtr<Worker> worker = adoptRef(new Worker(context));
635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    worker->suspendIfNeeded();
655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
6651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    KURL scriptURL = worker->resolveURL(url, exceptionState);
675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    if (scriptURL.isEmpty())
685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return 0;
695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // The worker context does not exist while loading, so we must ensure that the worker object is not collected, nor are its event listeners.
715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    worker->setPendingActivity(worker.get());
725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    worker->m_scriptLoader = WorkerScriptLoader::create();
745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    worker->m_scriptLoader->loadAsynchronously(context, scriptURL, DenyCrossOriginRequests, worker.get());
7551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    worker->m_contextProxy = proxyProvider->createWorkerGlobalScopeProxy(worker.get());
765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return worker.release();
775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)Worker::~Worker()
805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    ASSERT(isMainThread());
821e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    ASSERT(executionContext()); // The context is protected by worker context proxy, so it cannot be destroyed while a Worker exists.
8351b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (m_contextProxy)
8451b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)        m_contextProxy->workerObjectDestroyed();
855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)const AtomicString& Worker::interfaceName() const
885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
891e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    return EventTargetNames::Worker;
905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
9251b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)void Worker::postMessage(PassRefPtr<SerializedScriptValue> message, const MessagePortArray* ports, ExceptionState& exceptionState)
935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    // Disentangle the port in preparation for sending it to the remote context.
9551b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    OwnPtr<MessagePortChannelArray> channels = MessagePort::disentanglePorts(ports, exceptionState);
9651b2906e11752df6c18351cf520e30522d3b53a1Torne (Richard Coles)    if (exceptionState.hadException())
975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)        return;
98591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    m_contextProxy->postMessageToWorkerGlobalScope(message, channels.release());
995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void Worker::terminate()
1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
103591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch    m_contextProxy->terminateWorkerGlobalScope();
1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void Worker::stop()
1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    terminate();
1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)bool Worker::hasPendingActivity() const
1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    return m_contextProxy->hasPendingActivity() || ActiveDOMObject::hasPendingActivity();
1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void Worker::didReceiveResponse(unsigned long identifier, const ResourceResponse&)
1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
1181e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)    InspectorInstrumentation::didReceiveScriptResponse(executionContext(), identifier);
1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)void Worker::notifyFinished()
1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){
123c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    if (m_scriptLoader->failed()) {
1241e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        dispatchEvent(Event::createCancelable(EventTypeNames::error));
125c0e19a689c8ac22cdc96b291a8d33a5d3b0b34a4Torne (Richard Coles)    } else {
126591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch        WorkerThreadStartMode startMode = DontPauseWorkerGlobalScopeOnStart;
1271e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        if (InspectorInstrumentation::shouldPauseDedicatedWorkerOnStart(executionContext()))
128591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch            startMode = PauseWorkerGlobalScopeOnStart;
1291e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        m_contextProxy->startWorkerGlobalScope(m_scriptLoader->url(), executionContext()->userAgent(m_scriptLoader->url()), m_scriptLoader->script(), startMode);
1301e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)        InspectorInstrumentation::scriptImported(executionContext(), m_scriptLoader->identifier(), m_scriptLoader->script());
1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    }
1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    m_scriptLoader = nullptr;
1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    unsetPendingActivity(this);
1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} // namespace WebCore
138