| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2009 Google Inc. All rights reserved. | 2 * Copyright (C) 2009 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 53 #include "WorkerScriptLoaderClient.h" | 53 #include "WorkerScriptLoaderClient.h" |
| 54 | 54 |
| 55 namespace WebCore { | 55 namespace WebCore { |
| 56 | 56 |
| 57 class Document; | 57 class Document; |
| 58 using WebKit::WebFrameImpl;; | 58 using WebKit::WebFrameImpl;; |
| 59 using WebKit::WebMessagePortChannel; | 59 using WebKit::WebMessagePortChannel; |
| 60 using WebKit::WebSharedWorker; | 60 using WebKit::WebSharedWorker; |
| 61 using WebKit::WebSharedWorkerRepository; | 61 using WebKit::WebSharedWorkerRepository; |
| 62 | 62 |
| 63 // Callback class that keeps the Worker object alive while loads are potentially happening, and also translates load errors into error events on the worker. | 63 // Callback class that keeps the SharedWorker and WebSharedWorker objects alive while loads are potentially happening, and also translates load errors into error events on the worker. |
| 64 class SharedWorkerScriptLoader : public RefCounted<SharedWorkerScriptLoader>, private WorkerScriptLoaderClient { | 64 class SharedWorkerScriptLoader : private WorkerScriptLoaderClient, private WebSharedWorker::ConnectListener, private ActiveDOMObject { |
| 65 public: | 65 public: |
| 66 SharedWorkerScriptLoader(PassRefPtr<SharedWorker> worker, const KURL& url, const String& name, PassOwnPtr<MessagePortChannel> port, PassOwnPtr<WebSharedWorker> webWorker) | 66 SharedWorkerScriptLoader(PassRefPtr<SharedWorker> worker, const KURL& url, const String& name, PassOwnPtr<MessagePortChannel> port, PassOwnPtr<WebSharedWorker> webWorker) |
| 67 : m_worker(worker), | 67 : ActiveDOMObject(worker->scriptExecutionContext(), this) |
| 68 m_url(url), | 68 , m_worker(worker) |
| 69 m_name(name), | 69 , m_url(url) |
| 70 m_webWorker(webWorker), | 70 , m_name(name) |
| 71 m_port(port) | 71 , m_webWorker(webWorker) |
| 72 , m_port(port) |
| 72 { | 73 { |
| 73 } | 74 } |
| 74 | 75 |
| 75 void load(); | 76 void load(); |
| 76 | 77 virtual void contextDestroyed(); |
| 77 private: | 78 private: |
| 78 // WorkerScriptLoaderClient callback | 79 // WorkerScriptLoaderClient callback |
| 79 virtual void notifyFinished(); | 80 virtual void notifyFinished(); |
| 80 | 81 |
| 82 virtual void connected(); |
| 83 |
| 84 void sendConnect(); |
| 85 |
| 81 RefPtr<SharedWorker> m_worker; | 86 RefPtr<SharedWorker> m_worker; |
| 82 KURL m_url; | 87 KURL m_url; |
| 83 String m_name; | 88 String m_name; |
| 84 OwnPtr<WebSharedWorker> m_webWorker; | 89 OwnPtr<WebSharedWorker> m_webWorker; |
| 85 OwnPtr<MessagePortChannel> m_port; | 90 OwnPtr<MessagePortChannel> m_port; |
| 86 WorkerScriptLoader m_scriptLoader; | 91 WorkerScriptLoader m_scriptLoader; |
| 87 }; | 92 }; |
| 88 | 93 |
| 89 void SharedWorkerScriptLoader::load() | 94 void SharedWorkerScriptLoader::load() |
| 90 { | 95 { |
| 91 m_scriptLoader.loadAsynchronously(m_worker->scriptExecutionContext(), m_url, DenyCrossOriginRequests, this); | 96 // If the shared worker is not yet running, load the script resource for it, otherwise just send it a connect event. |
| 97 if (m_webWorker->isStarted()) |
| 98 sendConnect(); |
| 99 else |
| 100 m_scriptLoader.loadAsynchronously(m_worker->scriptExecutionContext(), m_url, DenyCrossOriginRequests, this); |
| 92 } | 101 } |
| 93 | 102 |
| 94 // Extracts a WebMessagePortChannel from a MessagePortChannel. | 103 // Extracts a WebMessagePortChannel from a MessagePortChannel. |
| 95 static WebMessagePortChannel* getWebPort(PassOwnPtr<MessagePortChannel> port) | 104 static WebMessagePortChannel* getWebPort(PassOwnPtr<MessagePortChannel> port) |
| 96 { | 105 { |
| 97 // Extract the WebMessagePortChannel to send to the worker. | 106 // Extract the WebMessagePortChannel to send to the worker. |
| 98 PlatformMessagePortChannel* platformChannel = port->channel(); | 107 PlatformMessagePortChannel* platformChannel = port->channel(); |
| 99 WebMessagePortChannel* webPort = platformChannel->webChannelRelease(); | 108 WebMessagePortChannel* webPort = platformChannel->webChannelRelease(); |
| 100 webPort->setClient(0); | 109 webPort->setClient(0); |
| 101 return webPort; | 110 return webPort; |
| 102 } | 111 } |
| 103 | 112 |
| 104 void SharedWorkerScriptLoader::notifyFinished() | 113 void SharedWorkerScriptLoader::notifyFinished() |
| 105 { | 114 { |
| 106 if (m_scriptLoader.failed()) | 115 if (m_scriptLoader.failed()) { |
| 107 m_worker->dispatchEvent(Event::create(eventNames().errorEvent, false, true)); | 116 m_worker->dispatchEvent(Event::create(eventNames().errorEvent, false, true)); |
| 108 else { | 117 delete this; |
| 118 } else { |
| 119 // Pass the script off to the worker, then send a connect event. |
| 109 m_webWorker->startWorkerContext(m_url, m_name, m_worker->scriptExecutionContext()->userAgent(m_url), m_scriptLoader.script()); | 120 m_webWorker->startWorkerContext(m_url, m_name, m_worker->scriptExecutionContext()->userAgent(m_url), m_scriptLoader.script()); |
| 110 m_webWorker->connect(getWebPort(m_port.release())); | 121 sendConnect(); |
| 111 } | 122 } |
| 123 } |
| 112 | 124 |
| 125 void SharedWorkerScriptLoader::sendConnect() |
| 126 { |
| 127 // Send the connect event off, and linger until it is done sending. |
| 128 m_webWorker->connect(getWebPort(m_port.release()), this); |
| 129 } |
| 130 |
| 131 void SharedWorkerScriptLoader::contextDestroyed() |
| 132 { |
| 133 ActiveDOMObject::contextDestroyed(); |
| 134 delete this; |
| 135 } |
| 136 |
| 137 void SharedWorkerScriptLoader::connected() |
| 138 { |
| 113 // Connect event has been sent, so free ourselves (this releases the SharedWorker so it can be freed as well if unreferenced). | 139 // Connect event has been sent, so free ourselves (this releases the SharedWorker so it can be freed as well if unreferenced). |
| 114 delete this; | 140 delete this; |
| 115 } | 141 } |
| 116 | 142 |
| 117 bool SharedWorkerRepository::isAvailable() | 143 bool SharedWorkerRepository::isAvailable() |
| 118 { | 144 { |
| 119 // Allow the WebKitClient to determine if SharedWorkers are available. | 145 // Allow the WebKitClient to determine if SharedWorkers are available. |
| 120 return WebKit::webKitClient()->sharedWorkerRepository(); | 146 return WebKit::webKitClient()->sharedWorkerRepository(); |
| 121 } | 147 } |
| 122 | 148 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 138 WebFrameImpl* webFrame = WebFrameImpl::fromFrame(document->frame()); | 164 WebFrameImpl* webFrame = WebFrameImpl::fromFrame(document->frame()); |
| 139 OwnPtr<WebSharedWorker> webWorker; | 165 OwnPtr<WebSharedWorker> webWorker; |
| 140 webWorker = webFrame->client()->createSharedWorker(webFrame, url, name, getId(document)); | 166 webWorker = webFrame->client()->createSharedWorker(webFrame, url, name, getId(document)); |
| 141 | 167 |
| 142 if (!webWorker) { | 168 if (!webWorker) { |
| 143 // Existing worker does not match this url, so return an error back to the caller. | 169 // Existing worker does not match this url, so return an error back to the caller. |
| 144 ec = URL_MISMATCH_ERR; | 170 ec = URL_MISMATCH_ERR; |
| 145 return; | 171 return; |
| 146 } | 172 } |
| 147 | 173 |
| 148 if (!webWorker->isStarted()) { | 174 // The loader object manages its own lifecycle (and the lifecycles of the two worker objects). |
| 149 // Need to kick off a load for the worker. The loader will connect to the worker once the script has been loaded, then free itself. | 175 // It will free itself once loading is completed. |
| 150 SharedWorkerScriptLoader* loader = new SharedWorkerScriptLoader(worker, url, name, port.release(), webWorker.release()); | 176 SharedWorkerScriptLoader* loader = new SharedWorkerScriptLoader(worker, url, name, port.release(), webWorker.release()); |
| 151 loader->load(); | 177 loader->load(); |
| 152 } else | |
| 153 webWorker->connect(getWebPort(port.release())); | |
| 154 } | 178 } |
| 155 | 179 |
| 156 void SharedWorkerRepository::documentDetached(Document* document) | 180 void SharedWorkerRepository::documentDetached(Document* document) |
| 157 { | 181 { |
| 158 WebSharedWorkerRepository* repo = WebKit::webKitClient()->sharedWorkerRepository(); | 182 WebSharedWorkerRepository* repo = WebKit::webKitClient()->sharedWorkerRepository(); |
| 159 if (repo) | 183 if (repo) |
| 160 repo->documentDetached(getId(document)); | 184 repo->documentDetached(getId(document)); |
| 161 } | 185 } |
| 162 | 186 |
| 163 bool SharedWorkerRepository::hasSharedWorkers(Document* document) | 187 bool SharedWorkerRepository::hasSharedWorkers(Document* document) |
| 164 { | 188 { |
| 165 WebSharedWorkerRepository* repo = WebKit::webKitClient()->sharedWorkerRepository(); | 189 WebSharedWorkerRepository* repo = WebKit::webKitClient()->sharedWorkerRepository(); |
| 166 return repo && repo->hasSharedWorkers(getId(document)); | 190 return repo && repo->hasSharedWorkers(getId(document)); |
| 167 } | 191 } |
| 168 | 192 |
| 169 | 193 |
| 170 | 194 |
| 171 } // namespace WebCore | 195 } // namespace WebCore |
| 172 | 196 |
| 173 #endif // ENABLE(SHARED_WORKERS) | 197 #endif // ENABLE(SHARED_WORKERS) |
| OLD | NEW |