blob: 724f64148c55a7e41acd4461dcef7bd3f3f970b2 [file] [log] [blame]
ap@webkit.orge2011e82008-11-16 09:11:54 +00001/*
darin@apple.combb381c72010-07-07 20:55:37 +00002 * Copyright (C) 2008, 2010 Apple Inc. All Rights Reserved.
ap@webkit.orga9c8bdb2009-02-12 09:08:37 +00003 * Copyright (C) 2009 Google Inc. All Rights Reserved.
ap@webkit.orge2011e82008-11-16 09:11:54 +00004 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 *
26 */
27
28#include "config.h"
29
30#if ENABLE(WORKERS)
31
32#include "Worker.h"
33
ap@webkit.orge2011e82008-11-16 09:11:54 +000034#include "DOMWindow.h"
abarth@webkit.org17d66c62010-09-08 10:26:02 +000035#include "CachedResourceLoader.h"
ap@webkit.orge2011e82008-11-16 09:11:54 +000036#include "Document.h"
37#include "EventException.h"
38#include "EventListener.h"
39#include "EventNames.h"
40#include "ExceptionCode.h"
ap@webkit.orgbf13f522008-12-09 17:58:10 +000041#include "Frame.h"
ap@webkit.orge2011e82008-11-16 09:11:54 +000042#include "FrameLoader.h"
yurys@chromium.org389a6242011-01-12 13:06:42 +000043#include "InspectorInstrumentation.h"
ap@webkit.orge2011e82008-11-16 09:11:54 +000044#include "MessageEvent.h"
dimich@chromium.org6be54ef2009-03-20 22:52:13 +000045#include "TextEncoding.h"
ap@webkit.orga9c8bdb2009-02-12 09:08:37 +000046#include "WorkerContextProxy.h"
jianli@chromium.org1d1a8362009-06-16 18:12:46 +000047#include "WorkerScriptLoader.h"
ap@webkit.orge2011e82008-11-16 09:11:54 +000048#include "WorkerThread.h"
49#include <wtf/MainThread.h>
50
51namespace WebCore {
52
darin@apple.combb381c72010-07-07 20:55:37 +000053inline Worker::Worker(ScriptExecutionContext* context)
levin@chromium.org1f1b9892009-07-17 19:11:26 +000054 : AbstractWorker(context)
ap@webkit.orga9c8bdb2009-02-12 09:08:37 +000055 , m_contextProxy(WorkerContextProxy::create(this))
ap@webkit.orge2011e82008-11-16 09:11:54 +000056{
darin@apple.combb381c72010-07-07 20:55:37 +000057}
jianli@chromium.orgd7d927d2009-07-30 01:10:06 +000058
darin@apple.combb381c72010-07-07 20:55:37 +000059PassRefPtr<Worker> Worker::create(const String& url, ScriptExecutionContext* context, ExceptionCode& ec)
60{
61 RefPtr<Worker> worker = adoptRef(new Worker(context));
62
63 KURL scriptURL = worker->resolveURL(url, ec);
64 if (scriptURL.isEmpty())
65 return 0;
66
darin@apple.combb381c72010-07-07 20:55:37 +000067 // The worker context does not exist while loading, so we must ensure that the worker object is not collected, nor are its event listeners.
68 worker->setPendingActivity(worker.get());
69
levin@chromium.org4e0bab22011-06-11 00:11:01 +000070 worker->m_scriptLoader = WorkerScriptLoader::create(ResourceRequestBase::TargetIsWorker);
71 worker->m_scriptLoader->loadAsynchronously(context, scriptURL, DenyCrossOriginRequests, worker.get());
72
pfeldman@chromium.org88146722011-01-17 10:44:50 +000073 InspectorInstrumentation::didCreateWorker(context, worker->asID(), scriptURL.string(), false);
darin@apple.combb381c72010-07-07 20:55:37 +000074
75 return worker.release();
ap@webkit.orge2011e82008-11-16 09:11:54 +000076}
77
78Worker::~Worker()
79{
80 ASSERT(isMainThread());
ap@webkit.orga9c8bdb2009-02-12 09:08:37 +000081 ASSERT(scriptExecutionContext()); // The context is protected by worker context proxy, so it cannot be destroyed while a Worker exists.
82 m_contextProxy->workerObjectDestroyed();
ap@webkit.orge2011e82008-11-16 09:11:54 +000083}
84
atwilson@chromium.org271695b2009-09-03 18:36:10 +000085// FIXME: remove this when we update the ObjC bindings (bug #28774).
oliver@apple.com0ef2c5b2009-10-07 02:06:03 +000086void Worker::postMessage(PassRefPtr<SerializedScriptValue> message, MessagePort* port, ExceptionCode& ec)
ap@webkit.orge2011e82008-11-16 09:11:54 +000087{
atwilson@chromium.org4a7bb132009-08-26 20:45:24 +000088 MessagePortArray ports;
89 if (port)
90 ports.append(port);
91 postMessage(message, &ports, ec);
levin@chromium.org0ea1cd82009-06-30 17:32:41 +000092}
93
oliver@apple.com0ef2c5b2009-10-07 02:06:03 +000094void Worker::postMessage(PassRefPtr<SerializedScriptValue> message, ExceptionCode& ec)
atwilson@chromium.org4a7bb132009-08-26 20:45:24 +000095{
96 postMessage(message, static_cast<MessagePortArray*>(0), ec);
97}
98
oliver@apple.com0ef2c5b2009-10-07 02:06:03 +000099void Worker::postMessage(PassRefPtr<SerializedScriptValue> message, const MessagePortArray* ports, ExceptionCode& ec)
levin@chromium.org0ea1cd82009-06-30 17:32:41 +0000100{
101 // Disentangle the port in preparation for sending it to the remote context.
atwilson@chromium.org4a7bb132009-08-26 20:45:24 +0000102 OwnPtr<MessagePortChannelArray> channels = MessagePort::disentanglePorts(ports, ec);
levin@chromium.org0ea1cd82009-06-30 17:32:41 +0000103 if (ec)
104 return;
atwilson@chromium.org4a7bb132009-08-26 20:45:24 +0000105 m_contextProxy->postMessageToWorkerContext(message, channels.release());
ap@webkit.orge2011e82008-11-16 09:11:54 +0000106}
107
ap@webkit.orge149b892008-11-24 18:21:03 +0000108void Worker::terminate()
109{
ap@webkit.orga9c8bdb2009-02-12 09:08:37 +0000110 m_contextProxy->terminateWorkerContext();
ap@webkit.orge149b892008-11-24 18:21:03 +0000111}
112
ap@webkit.org773343a2008-12-03 07:42:38 +0000113bool Worker::canSuspend() const
114{
115 // FIXME: It is not currently possible to suspend a worker, so pages with workers can not go into page cache.
116 return false;
117}
118
119void Worker::stop()
120{
121 terminate();
122}
123
ap@webkit.orgfacdd7c2008-11-18 08:44:40 +0000124bool Worker::hasPendingActivity() const
125{
ap@webkit.orga9c8bdb2009-02-12 09:08:37 +0000126 return m_contextProxy->hasPendingActivity() || ActiveDOMObject::hasPendingActivity();
ap@webkit.orgfacdd7c2008-11-18 08:44:40 +0000127}
128
jianli@chromium.org1d1a8362009-06-16 18:12:46 +0000129void Worker::notifyFinished()
ap@webkit.orge2011e82008-11-16 09:11:54 +0000130{
jianli@chromium.org1d1a8362009-06-16 18:12:46 +0000131 if (m_scriptLoader->failed())
ggaren@apple.com521f64b2009-09-24 05:53:23 +0000132 dispatchEvent(Event::create(eventNames().errorEvent, false, true));
eric@webkit.orgc8307722010-03-26 16:34:12 +0000133 else {
jianli@chromium.org4385f842009-07-15 23:15:40 +0000134 m_contextProxy->startWorkerContext(m_scriptLoader->url(), scriptExecutionContext()->userAgent(m_scriptLoader->url()), m_scriptLoader->script());
yurys@chromium.org5189c7c2011-06-24 05:42:25 +0000135 InspectorInstrumentation::didStartWorkerContext(scriptExecutionContext(), m_contextProxy, m_scriptLoader->url());
yurys@chromium.org389a6242011-01-12 13:06:42 +0000136 InspectorInstrumentation::scriptImported(scriptExecutionContext(), m_scriptLoader->identifier(), m_scriptLoader->script());
eric@webkit.orgc8307722010-03-26 16:34:12 +0000137 }
levin@chromium.orgdae148a82011-04-27 06:08:32 +0000138 m_scriptLoader = nullptr;
ap@webkit.orge2011e82008-11-16 09:11:54 +0000139
140 unsetPendingActivity(this);
141}
142
ap@webkit.orge2011e82008-11-16 09:11:54 +0000143} // namespace WebCore
144
145#endif // ENABLE(WORKERS)