2 * Copyright (C) 2008, 2010 Apple Inc. All Rights Reserved.
3 * Copyright (C) 2009 Google Inc. All Rights Reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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.
34 #include "DOMWindow.h"
35 #include "CachedResourceLoader.h"
37 #include "EventException.h"
38 #include "EventListener.h"
39 #include "EventNames.h"
40 #include "ExceptionCode.h"
42 #include "FrameLoader.h"
43 #include "InspectorInstrumentation.h"
44 #include "MessageEvent.h"
45 #include "TextEncoding.h"
46 #include "WorkerContextProxy.h"
47 #include "WorkerScriptLoader.h"
48 #include "WorkerThread.h"
49 #include <wtf/MainThread.h>
53 inline Worker::Worker(ScriptExecutionContext* context)
54 : AbstractWorker(context)
55 , m_contextProxy(WorkerContextProxy::create(this))
59 PassRefPtr<Worker> Worker::create(const String& url, ScriptExecutionContext* context, ExceptionCode& ec)
61 RefPtr<Worker> worker = adoptRef(new Worker(context));
63 KURL scriptURL = worker->resolveURL(url, ec);
64 if (scriptURL.isEmpty())
67 // 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());
70 worker->m_scriptLoader = WorkerScriptLoader::create();
71 #if PLATFORM(CHROMIUM)
72 worker->m_scriptLoader->setTargetType(ResourceRequest::TargetIsWorker);
74 worker->m_scriptLoader->loadAsynchronously(context, scriptURL, DenyCrossOriginRequests, worker.get());
76 InspectorInstrumentation::didCreateWorker(context, worker->asID(), scriptURL.string(), false);
78 return worker.release();
83 ASSERT(isMainThread());
84 ASSERT(scriptExecutionContext()); // The context is protected by worker context proxy, so it cannot be destroyed while a Worker exists.
85 m_contextProxy->workerObjectDestroyed();
88 // FIXME: remove this when we update the ObjC bindings (bug #28774).
89 void Worker::postMessage(PassRefPtr<SerializedScriptValue> message, MessagePort* port, ExceptionCode& ec)
91 MessagePortArray ports;
94 postMessage(message, &ports, ec);
97 void Worker::postMessage(PassRefPtr<SerializedScriptValue> message, ExceptionCode& ec)
99 postMessage(message, static_cast<MessagePortArray*>(0), ec);
102 void Worker::postMessage(PassRefPtr<SerializedScriptValue> message, const MessagePortArray* ports, ExceptionCode& ec)
104 // Disentangle the port in preparation for sending it to the remote context.
105 OwnPtr<MessagePortChannelArray> channels = MessagePort::disentanglePorts(ports, ec);
108 m_contextProxy->postMessageToWorkerContext(message, channels.release());
111 void Worker::terminate()
113 m_contextProxy->terminateWorkerContext();
116 bool Worker::canSuspend() const
118 // FIXME: It is not currently possible to suspend a worker, so pages with workers can not go into page cache.
127 bool Worker::hasPendingActivity() const
129 return m_contextProxy->hasPendingActivity() || ActiveDOMObject::hasPendingActivity();
132 void Worker::didReceiveResponse(unsigned long identifier, const ResourceResponse&)
134 InspectorInstrumentation::didReceiveScriptResponse(scriptExecutionContext(), identifier);
137 void Worker::notifyFinished()
139 if (m_scriptLoader->failed())
140 dispatchEvent(Event::create(eventNames().errorEvent, false, true));
142 m_contextProxy->startWorkerContext(m_scriptLoader->url(), scriptExecutionContext()->userAgent(m_scriptLoader->url()), m_scriptLoader->script());
143 InspectorInstrumentation::didStartWorkerContext(scriptExecutionContext(), m_contextProxy, m_scriptLoader->url());
144 InspectorInstrumentation::scriptImported(scriptExecutionContext(), m_scriptLoader->identifier(), m_scriptLoader->script());
146 m_scriptLoader = nullptr;
148 unsetPendingActivity(this);
151 } // namespace WebCore
153 #endif // ENABLE(WORKERS)