1643ca7872b450ea4efacab6188849e5aac2ba161Steve Block/*
2643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * Copyright (C) 2009 Google Inc. All rights reserved.
3643ca7872b450ea4efacab6188849e5aac2ba161Steve Block *
4643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * Redistribution and use in source and binary forms, with or without
5643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * modification, are permitted provided that the following conditions are
6643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * met:
7643ca7872b450ea4efacab6188849e5aac2ba161Steve Block *
8643ca7872b450ea4efacab6188849e5aac2ba161Steve Block *     * Redistributions of source code must retain the above copyright
9643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * notice, this list of conditions and the following disclaimer.
10643ca7872b450ea4efacab6188849e5aac2ba161Steve Block *     * Redistributions in binary form must reproduce the above
11643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * copyright notice, this list of conditions and the following disclaimer
12643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * in the documentation and/or other materials provided with the
13643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * distribution.
14643ca7872b450ea4efacab6188849e5aac2ba161Steve Block *     * Neither the name of Google Inc. nor the names of its
15643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * contributors may be used to endorse or promote products derived from
16643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * this software without specific prior written permission.
17643ca7872b450ea4efacab6188849e5aac2ba161Steve Block *
18643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29643ca7872b450ea4efacab6188849e5aac2ba161Steve Block */
30643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
31643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "config.h"
32643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "WebWorkerImpl.h"
33643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
34e78cbe89e6f337f2f1fe40315be88f742b547151Steve Block#include "CrossThreadTask.h"
35643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "DedicatedWorkerContext.h"
36643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "DedicatedWorkerThread.h"
37643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "KURL.h"
38643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "MessageEvent.h"
39643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "MessagePort.h"
40643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "MessagePortChannel.h"
41643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "ScriptExecutionContext.h"
42643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "SecurityOrigin.h"
43643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "SerializedScriptValue.h"
44643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "SubstituteData.h"
45643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include <wtf/Threading.h>
46643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
47643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "PlatformMessagePortChannel.h"
48643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "WebMessagePortChannel.h"
49643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "WebString.h"
50643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "WebURL.h"
51643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "WebWorkerClient.h"
52643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
53643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockusing namespace WebCore;
54643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
55643ca7872b450ea4efacab6188849e5aac2ba161Steve Blocknamespace WebKit {
56643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
57643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#if ENABLE(WORKERS)
58643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
59643ca7872b450ea4efacab6188849e5aac2ba161Steve BlockWebWorker* WebWorker::create(WebWorkerClient* client)
60643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
61643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return new WebWorkerImpl(client);
62643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
63643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
64643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
65643ca7872b450ea4efacab6188849e5aac2ba161Steve BlockWebWorkerImpl::WebWorkerImpl(WebWorkerClient* client)
66643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    : m_client(client)
67643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
68643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
69643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
70643ca7872b450ea4efacab6188849e5aac2ba161Steve BlockWebWorkerImpl::~WebWorkerImpl()
71643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
72643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
73643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
74643ca7872b450ea4efacab6188849e5aac2ba161Steve BlockWebCommonWorkerClient* WebWorkerImpl::commonClient()
75643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
76643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return m_client;
77643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
78643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
79643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockvoid WebWorkerImpl::postMessageToWorkerContextTask(WebCore::ScriptExecutionContext* context,
80643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                                                   WebWorkerImpl* thisPtr,
81643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                                                   const String& message,
82643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                                                   PassOwnPtr<MessagePortChannelArray> channels)
83643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
84643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    ASSERT(context->isWorkerContext());
85643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    DedicatedWorkerContext* workerContext =
86643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        static_cast<DedicatedWorkerContext*>(context);
87643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
88643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    OwnPtr<MessagePortArray> ports =
89e458d70a0d18538346f41b503114c9ebe6b2ce12Leon Clarke        MessagePort::entanglePorts(*context, channels);
90643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    RefPtr<SerializedScriptValue> serializedMessage =
91d0825bca7fe65beaee391d30da42e937db621564Steve Block        SerializedScriptValue::createFromWire(message);
92643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    workerContext->dispatchEvent(MessageEvent::create(
93643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        ports.release(), serializedMessage.release()));
94643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    thisPtr->confirmMessageFromWorkerObject(workerContext->hasPendingActivity());
95643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
96643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
97643ca7872b450ea4efacab6188849e5aac2ba161Steve Block// WebWorker -------------------------------------------------------------------
98643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
99643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockvoid WebWorkerImpl::startWorkerContext(const WebURL& scriptUrl,
100643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                                       const WebString& userAgent,
101643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                                       const WebString& sourceCode)
102643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
103643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    initializeLoader(scriptUrl);
104643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    setWorkerThread(DedicatedWorkerThread::create(scriptUrl, userAgent,
105643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                                                  sourceCode, *this, *this));
106643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // Worker initialization means a pending activity.
107643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    reportPendingActivity(true);
108643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    workerThread()->start();
109643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
110643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
111643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockvoid WebWorkerImpl::terminateWorkerContext()
112643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
113643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    stopWorkerThread();
114643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
115643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
116643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockvoid WebWorkerImpl::postMessageToWorkerContext(const WebString& message,
117643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                                               const WebMessagePortChannelArray& webChannels)
118643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
119643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    OwnPtr<MessagePortChannelArray> channels;
120643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    if (webChannels.size()) {
121643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        channels = new MessagePortChannelArray(webChannels.size());
122643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        for (size_t i = 0; i < webChannels.size(); ++i) {
123643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            RefPtr<PlatformMessagePortChannel> platform_channel =
124643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                PlatformMessagePortChannel::create(webChannels[i]);
125643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            webChannels[i]->setClient(platform_channel.get());
126643ca7872b450ea4efacab6188849e5aac2ba161Steve Block            (*channels)[i] = MessagePortChannel::create(platform_channel);
127643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        }
128643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    }
129643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
130643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    workerThread()->runLoop().postTask(
131643ca7872b450ea4efacab6188849e5aac2ba161Steve Block        createCallbackTask(&postMessageToWorkerContextTask,
132643ca7872b450ea4efacab6188849e5aac2ba161Steve Block                           this, String(message), channels.release()));
133643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
134643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
135643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockvoid WebWorkerImpl::workerObjectDestroyed()
136643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
137643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // Worker object in the renderer was destroyed, perhaps a result of GC.
138643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // For us, it's a signal to start terminating the WorkerContext too.
139643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // FIXME: when 'kill a worker' html5 spec algorithm is implemented, it
140643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    // should be used here instead of 'terminate a worker'.
141643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    terminateWorkerContext();
142643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
143643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
144643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockvoid WebWorkerImpl::clientDestroyed()
145643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
146643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    m_client = 0;
147643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
148643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
149643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#else
150643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
151643ca7872b450ea4efacab6188849e5aac2ba161Steve BlockWebWorker* WebWorker::create(WebWorkerClient* client)
152643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{
153643ca7872b450ea4efacab6188849e5aac2ba161Steve Block    return 0;
154643ca7872b450ea4efacab6188849e5aac2ba161Steve Block}
155643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
156643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#endif // ENABLE(WORKERS)
157643ca7872b450ea4efacab6188849e5aac2ba161Steve Block
158643ca7872b450ea4efacab6188849e5aac2ba161Steve Block} // namespace WebKit
159