• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2009 Google Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  *     * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *     * Redistributions in binary form must reproduce the above
11  * copyright notice, this list of conditions and the following disclaimer
12  * in the documentation and/or other materials provided with the
13  * distribution.
14  *     * Neither the name of Google Inc. nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 #include "config.h"
32 #include "WebWorkerImpl.h"
33 
34 #include "CrossThreadTask.h"
35 #include "DedicatedWorkerContext.h"
36 #include "DedicatedWorkerThread.h"
37 #include "KURL.h"
38 #include "MessageEvent.h"
39 #include "MessagePort.h"
40 #include "MessagePortChannel.h"
41 #include "ScriptExecutionContext.h"
42 #include "SecurityOrigin.h"
43 #include "SerializedScriptValue.h"
44 #include "SubstituteData.h"
45 #include <wtf/Threading.h>
46 
47 #include "PlatformMessagePortChannel.h"
48 #include "WebMessagePortChannel.h"
49 #include "WebString.h"
50 #include "WebURL.h"
51 #include "WebWorkerClient.h"
52 
53 using namespace WebCore;
54 
55 namespace WebKit {
56 
57 #if ENABLE(WORKERS)
58 
create(WebWorkerClient * client)59 WebWorker* WebWorker::create(WebWorkerClient* client)
60 {
61     return new WebWorkerImpl(client);
62 }
63 
64 
WebWorkerImpl(WebWorkerClient * client)65 WebWorkerImpl::WebWorkerImpl(WebWorkerClient* client)
66     : m_client(client)
67 {
68 }
69 
~WebWorkerImpl()70 WebWorkerImpl::~WebWorkerImpl()
71 {
72 }
73 
commonClient()74 WebCommonWorkerClient* WebWorkerImpl::commonClient()
75 {
76     return m_client;
77 }
78 
postMessageToWorkerContextTask(WebCore::ScriptExecutionContext * context,WebWorkerImpl * thisPtr,const String & message,PassOwnPtr<MessagePortChannelArray> channels)79 void WebWorkerImpl::postMessageToWorkerContextTask(WebCore::ScriptExecutionContext* context,
80                                                    WebWorkerImpl* thisPtr,
81                                                    const String& message,
82                                                    PassOwnPtr<MessagePortChannelArray> channels)
83 {
84     ASSERT(context->isWorkerContext());
85     DedicatedWorkerContext* workerContext =
86         static_cast<DedicatedWorkerContext*>(context);
87 
88     OwnPtr<MessagePortArray> ports =
89         MessagePort::entanglePorts(*context, channels);
90     RefPtr<SerializedScriptValue> serializedMessage =
91         SerializedScriptValue::createFromWire(message);
92     workerContext->dispatchEvent(MessageEvent::create(
93         ports.release(), serializedMessage.release()));
94     thisPtr->confirmMessageFromWorkerObject(workerContext->hasPendingActivity());
95 }
96 
97 // WebWorker -------------------------------------------------------------------
98 
startWorkerContext(const WebURL & scriptUrl,const WebString & userAgent,const WebString & sourceCode)99 void WebWorkerImpl::startWorkerContext(const WebURL& scriptUrl,
100                                        const WebString& userAgent,
101                                        const WebString& sourceCode)
102 {
103     initializeLoader(scriptUrl);
104     setWorkerThread(DedicatedWorkerThread::create(scriptUrl, userAgent,
105                                                   sourceCode, *this, *this));
106     // Worker initialization means a pending activity.
107     reportPendingActivity(true);
108     workerThread()->start();
109 }
110 
terminateWorkerContext()111 void WebWorkerImpl::terminateWorkerContext()
112 {
113     stopWorkerThread();
114 }
115 
postMessageToWorkerContext(const WebString & message,const WebMessagePortChannelArray & webChannels)116 void WebWorkerImpl::postMessageToWorkerContext(const WebString& message,
117                                                const WebMessagePortChannelArray& webChannels)
118 {
119     OwnPtr<MessagePortChannelArray> channels;
120     if (webChannels.size()) {
121         channels = new MessagePortChannelArray(webChannels.size());
122         for (size_t i = 0; i < webChannels.size(); ++i) {
123             RefPtr<PlatformMessagePortChannel> platform_channel =
124                 PlatformMessagePortChannel::create(webChannels[i]);
125             webChannels[i]->setClient(platform_channel.get());
126             (*channels)[i] = MessagePortChannel::create(platform_channel);
127         }
128     }
129 
130     workerThread()->runLoop().postTask(
131         createCallbackTask(&postMessageToWorkerContextTask,
132                            this, String(message), channels.release()));
133 }
134 
workerObjectDestroyed()135 void WebWorkerImpl::workerObjectDestroyed()
136 {
137     // Worker object in the renderer was destroyed, perhaps a result of GC.
138     // For us, it's a signal to start terminating the WorkerContext too.
139     // FIXME: when 'kill a worker' html5 spec algorithm is implemented, it
140     // should be used here instead of 'terminate a worker'.
141     terminateWorkerContext();
142 }
143 
clientDestroyed()144 void WebWorkerImpl::clientDestroyed()
145 {
146     m_client = 0;
147 }
148 
149 #else
150 
151 WebWorker* WebWorker::create(WebWorkerClient* client)
152 {
153     return 0;
154 }
155 
156 #endif // ENABLE(WORKERS)
157 
158 } // namespace WebKit
159