diff options
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/worker_host/worker_process_host.cc | 5 | ||||
-rw-r--r-- | chrome/chrome.gyp | 4 | ||||
-rw-r--r-- | chrome/common/chrome_switches.cc | 3 | ||||
-rw-r--r-- | chrome/common/chrome_switches.h | 1 | ||||
-rw-r--r-- | chrome/installer/installer.gyp | 2 | ||||
-rw-r--r-- | chrome/worker/nativewebworker_impl.cc | 159 | ||||
-rw-r--r-- | chrome/worker/nativewebworker_impl.h | 44 | ||||
-rw-r--r-- | chrome/worker/nativewebworker_stub.cc | 46 | ||||
-rw-r--r-- | chrome/worker/nativewebworker_stub.h | 63 | ||||
-rw-r--r-- | chrome/worker/webworkerclient_proxy.cc | 29 |
10 files changed, 353 insertions, 3 deletions
diff --git a/chrome/browser/worker_host/worker_process_host.cc b/chrome/browser/worker_host/worker_process_host.cc index 34089c1..ecf8a3d 100644 --- a/chrome/browser/worker_host/worker_process_host.cc +++ b/chrome/browser/worker_host/worker_process_host.cc @@ -80,6 +80,11 @@ bool WorkerProcessHost::Init() { ASCIIToWide(channel_id())); if (CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnableNativeWebWorkers)) { + cmd_line.AppendSwitch(switches::kEnableNativeWebWorkers); + } + + if (CommandLine::ForCurrentProcess()->HasSwitch( switches::kWebWorkerShareProcesses)) { cmd_line.AppendSwitch(switches::kWebWorkerShareProcesses); } diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp index 0e26aba..2452480 100644 --- a/chrome/chrome.gyp +++ b/chrome/chrome.gyp @@ -4779,6 +4779,10 @@ 'tools/build/win/precompiled.cc', 'tools/build/win/precompiled.h', + 'worker/nativewebworker_impl.cc', + 'worker/nativewebworker_impl.h', + 'worker/nativewebworker_stub.cc', + 'worker/nativewebworker_stub.h', 'worker/webworkerclient_proxy.cc', 'worker/webworkerclient_proxy.h', 'worker/worker_main.cc', diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc index 8f99057..df64097 100644 --- a/chrome/common/chrome_switches.cc +++ b/chrome/common/chrome_switches.cc @@ -440,6 +440,9 @@ const wchar_t kIPCUseFIFO[] = L"ipc-use-fifo"; // Enable HTML5 Worker support const wchar_t kEnableWebWorkers[] = L"enable-web-workers"; +// Enable Native Web Worker support +const wchar_t kEnableNativeWebWorkers[] = L"enable-native-web-workers"; + // Causes the worker process allocation to use as many processes as cores. const wchar_t kWebWorkerProcessPerCore[] = L"web-worker-process-per-core"; diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h index 5663946..75e326e 100644 --- a/chrome/common/chrome_switches.h +++ b/chrome/common/chrome_switches.h @@ -164,6 +164,7 @@ extern const wchar_t kNewFtp[]; extern const wchar_t kIPCUseFIFO[]; extern const wchar_t kEnableWebWorkers[]; +extern const wchar_t kEnableNativeWebWorkers[]; extern const wchar_t kWebWorkerProcessPerCore[]; extern const wchar_t kWebWorkerShareProcesses[]; diff --git a/chrome/installer/installer.gyp b/chrome/installer/installer.gyp index babfd2e..cc20252 100644 --- a/chrome/installer/installer.gyp +++ b/chrome/installer/installer.gyp @@ -347,7 +347,7 @@ 'shlwapi.lib', ], 'AdditionalLibraryDirectories': - '<(DEPTH)/third_party/platformsdk_win2008_6_1/files/Lib;<(PRODUCT_DIR)/lib', + ['<(DEPTH)/third_party/platformsdk_win2008_6_1/files/Lib;<(PRODUCT_DIR)/lib'], 'AdditionalOptions': '/safeseh:NO /dynamicbase:no /nxcompat /fixed', 'DelayLoadDLLs=': [], diff --git a/chrome/worker/nativewebworker_impl.cc b/chrome/worker/nativewebworker_impl.cc new file mode 100644 index 0000000..5f12041 --- /dev/null +++ b/chrome/worker/nativewebworker_impl.cc @@ -0,0 +1,159 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/worker/nativewebworker_impl.h" + +#include "base/compiler_specific.h" + +#undef LOG + +#include "base/logging.h" +#include "webkit/glue/glue_util.h" +#include "base/thread.h" +#include "webkit/api/public/WebString.h" +#include "webkit/api/public/WebURL.h" +#include "webkit/api/public/WebKitClient.h" +#include "webkit/api/public/WebWorkerClient.h" + +// TODO(sehr): This will be changed to point to the real NaCl headers once +// the builds are integrated. +#include "chrome/worker/nativewebworker_stub.h" + +namespace { +// Remember the main thread's message loop, so that the listener thread +// can post messages to it when the worker wants to post to the renderer. +static MessageLoop* g_main_thread_message_loop; + +// PostMessageTask encapsulates sending messages from native web workers to +// the renderer by placing them on the main thread's message loop. +class PostMessageTask : public Task { + public: + PostMessageTask(const char* bufp, WebKit::WebWorkerClient* client) + : message_string_(WebKit::WebString::fromUTF8(bufp)), + client_(client) { + } + ~PostMessageTask() { } + void Run() { + client_->postMessageToWorkerObject(message_string_); + } + + private: + WebKit::WebString message_string_; + WebKit::WebWorkerClient* client_; + + DISALLOW_COPY_AND_ASSIGN(PostMessageTask); +}; + +// PostToRenderer places a string in bufp in a message and enqueues +// a task to send the message to the renderer. +static void PostToRenderer(const char* bufp, + WebKit::WebWorkerClient* client) { + g_main_thread_message_loop->PostTask(FROM_HERE, + new PostMessageTask(bufp, client)); +} + +class ListenerTask : public Task { + public: + ListenerTask(WebKit::WebWorkerClient* client, + struct NaClDesc* chrome_desc) + : client_(client), + chrome_desc_(chrome_desc) { } + ~ListenerTask() { } + void Run() { + NaClSrpcListenerLoop(chrome_desc_, PostToRenderer, client_); + } + + private: + WebKit::WebWorkerClient* client_; + struct NaClDesc* chrome_desc_; + + DISALLOW_COPY_AND_ASSIGN(ListenerTask); +}; +} + +// NativeWebWorkerListenerThread encapsulates a listener for SRPC messages from +// native web workers. +class NativeWebWorkerListenerThread : public base::Thread { + public: + explicit NativeWebWorkerListenerThread(const char* str) : Thread(str) { } + ~NativeWebWorkerListenerThread() {} + static NativeWebWorkerListenerThread* Create() { + return new NativeWebWorkerListenerThread("NativeWebWorkerListener"); + } + + private: + DISALLOW_COPY_AND_ASSIGN(NativeWebWorkerListenerThread); +}; + +// Utility function to convert to C strings. +static char* WebStringToCharp(const WebKit::WebString& str, size_t* len) { + // Convert source from webString data to char* + *len = str.length(); + char* bufp = new char[*len + 1]; + const WebKit::WebUChar* datap = str.data(); + for (size_t i = 0; i < *len; ++i) { + bufp[i] = static_cast<char>(datap[i]); + } + bufp[*len] = 0; + return bufp; +} + +// Used for debugging purposes for now. +static int retval; + +WebKit::WebWorker* NativeWebWorkerImpl::create( + WebKit::WebWorkerClient* client) { + return new NativeWebWorkerImpl(client); +} + +NativeWebWorkerImpl::NativeWebWorkerImpl(WebKit::WebWorkerClient* client) + : client_(client) { +} + +NativeWebWorkerImpl::~NativeWebWorkerImpl() { +} + +void NativeWebWorkerImpl::startWorkerContext(const WebKit::WebURL& script_url, + const WebKit::WebString& user_agent, + const WebKit::WebString& source) { + size_t len; + char* bufp = WebStringToCharp(source, &len); + // Start NaCl using the nexe. + retval = NaClStartNativeWebWorker(bufp, len, &nap_, &channel_); + // Free the string. + delete[] bufp; + + // Remember the main thread's message loop. + g_main_thread_message_loop = MessageLoop::current(); + // Start the upcall listener thread. + upcall_thread_ = NativeWebWorkerListenerThread::Create(); + upcall_thread_->Start(); + // Put an SRPC listener loop on the listener thread. + NaClCreateUpcallChannel(descs_); + Task* task = new ListenerTask(client_, descs_[1]); + upcall_thread_->message_loop()->PostTask(FROM_HERE, task); + // Send upcall listener channel descriptor to the native worker. + retval = NaClSrpcSendUpcallDesc(channel_, descs_[0]); +} + +void NativeWebWorkerImpl::terminateWorkerContext() { + // Close the descriptors. + NaClDestroyUpcallChannel(descs_); + // Shut down the sel_ldr instance for this native web worker. + retval = NaClTerminateNativeWebWorker(&nap_, &channel_); + // Shut down the upcall thread. + upcall_thread_->Stop(); +} + +void NativeWebWorkerImpl::postMessageToWorkerContext( + const WebKit::WebString& message) { + size_t len; + char* bufp = WebStringToCharp(message, &len); + // Send a message to NaCl object + retval = NaClPostMessageToNativeWebWorker(bufp, len, &nap_, &channel_); + delete[] bufp; +} + +void NativeWebWorkerImpl::workerObjectDestroyed() { +} diff --git a/chrome/worker/nativewebworker_impl.h b/chrome/worker/nativewebworker_impl.h new file mode 100644 index 0000000..5449e38 --- /dev/null +++ b/chrome/worker/nativewebworker_impl.h @@ -0,0 +1,44 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_WORKER_NATIVEWORKER_H_ +#define CHROME_WORKER_NATIVEWORKER_H_ + +#include "base/basictypes.h" +#include "webkit/api/public/WebWorker.h" +#include "webkit/api/public/WebWorkerClient.h" + + +// Forward declaration for the listener thread pointer. +class NativeWebWorkerListenerThread; + +// This class is used by the worker process code to talk to the Native Client +// worker implementation. +class NativeWebWorkerImpl : public WebKit::WebWorker { + public: + explicit NativeWebWorkerImpl(WebKit::WebWorkerClient* client); + virtual ~NativeWebWorkerImpl(); + + static WebWorker* NativeWebWorkerImpl::create( + WebKit::WebWorkerClient* client); + + // WebWorker implementation. + void startWorkerContext(const WebKit::WebURL& script_url, + const WebKit::WebString& user_agent, + const WebKit::WebString& source_code); + void terminateWorkerContext(); + void postMessageToWorkerContext(const WebKit::WebString& message); + void workerObjectDestroyed(); + + private: + WebKit::WebWorkerClient* client_; + struct NaClApp* nap_; + struct NaClSrpcChannel* channel_; + NativeWebWorkerListenerThread* upcall_thread_; + struct NaClDesc* descs_[2]; + + DISALLOW_COPY_AND_ASSIGN(NativeWebWorkerImpl); +}; + +#endif // CHROME_WORKER_NATIVEWEBWORKER_H_ diff --git a/chrome/worker/nativewebworker_stub.cc b/chrome/worker/nativewebworker_stub.cc new file mode 100644 index 0000000..1abdc87 --- /dev/null +++ b/chrome/worker/nativewebworker_stub.cc @@ -0,0 +1,46 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Native WebWorker stubs. +// Please note that this implementation is used only until the native client +// build is invokable from within Chromium. + +#include "chrome/worker/nativewebworker_stub.h" + +int NaClStartNativeWebWorker(char *buffer, + size_t buf_len, + NaClApp **nap, + NaClSrpcChannel **untrusted_channel) { + return 0; +} + +int NaClPostMessageToNativeWebWorker(char *buffer, + size_t buf_len, + NaClApp **nap, + NaClSrpcChannel **untrusted_ch) { + return 0; +} + +int NaClTerminateNativeWebWorker(NaClApp **nap, + NaClSrpcChannel **untrusted_channel) { + return 0; +} + +int NaClCreateUpcallChannel(NaClDesc* desc[2]) { + return 0; +} + +int NaClSrpcSendUpcallDesc(NaClSrpcChannel *channel, + NaClDesc *nacl_desc) { + return 0; +} + +int NaClSrpcListenerLoop(NaClDesc *chrome_desc, + NativeWorkerPostMessageFunc func, + WebKit::WebWorkerClient* client) { + return 0; +} + +void NaClDestroyUpcallChannel(NaClDesc* desc[2]) { +} diff --git a/chrome/worker/nativewebworker_stub.h b/chrome/worker/nativewebworker_stub.h new file mode 100644 index 0000000..6afe1db --- /dev/null +++ b/chrome/worker/nativewebworker_stub.h @@ -0,0 +1,63 @@ +// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_WORKER_NATIVEWORKER_STUB_H_ +#define CHROME_WORKER_NATIVEWORKER_STUB_H_ +// Native WebWorker support stub header. + +#include <stddef.h> + +// As we are not including the native client header files, several types +// from them need to be named outside of structure/method declarations to +// avoid compiler warnings/errors. + +struct NaClApp; +struct NaClDesc; +struct NaClSrpcChannel; + +namespace WebKit { +class WebWorkerClient; +} + +extern "C" { +// The thunk type used by upcall (postMessage from worker) handling. +typedef void (*NativeWorkerPostMessageFunc)(const char *str, + WebKit::WebWorkerClient* client); + +// Start a native webworker from the module in buffer. +int NaClStartNativeWebWorker(char *buffer, + size_t buf_len, + struct NaClApp **nap, + struct NaClSrpcChannel **untrusted_channel); + +// Performs a postMessage to the worker. +int NaClPostMessageToNativeWebWorker(char *buffer, + size_t buf_len, + struct NaClApp **nap, + struct NaClSrpcChannel **untrusted_ch); + +// Causes a native web worker to be shut down. +int NaClTerminateNativeWebWorker(struct NaClApp **nap, + struct NaClSrpcChannel **untrusted_channel); + +// Creates a channel that can be used to receive upcalls (postMessage from +// a worker). +int NaClCreateUpcallChannel(struct NaClDesc* desc[2]); + +// Part of the initialization of a worker. Sends the descriptor to the +// worker library to indicate where to send postMessage RPCs. +int NaClSrpcSendUpcallDesc(struct NaClSrpcChannel *channel, + struct NaClDesc *nacl_desc); + +// Runs an SRPC server loop on the specified channel. The post_message_func +// is invoked whenever the "postMessage" RPC is received. +int NaClSrpcListenerLoop(struct NaClDesc *chrome_desc, + NativeWorkerPostMessageFunc func, + WebKit::WebWorkerClient* client); + +// Destroys the upcall channel. +void NaClDestroyUpcallChannel(struct NaClDesc* desc[2]); +} + +#endif // CHROME_WORKER_NATIVEWORKER_STUB_H_ diff --git a/chrome/worker/webworkerclient_proxy.cc b/chrome/worker/webworkerclient_proxy.cc index 8a0a6f1..85a410b 100644 --- a/chrome/worker/webworkerclient_proxy.cc +++ b/chrome/worker/webworkerclient_proxy.cc @@ -11,6 +11,7 @@ #include "chrome/common/worker_messages.h" #include "chrome/renderer/webworker_proxy.h" #include "chrome/worker/worker_thread.h" +#include "chrome/worker/nativewebworker_impl.h" #include "webkit/api/public/WebString.h" #include "webkit/api/public/WebURL.h" #include "webkit/api/public/WebWorker.h" @@ -39,10 +40,34 @@ class KillProcessTask : public Task { } +static bool UrlIsNativeWorker(const GURL& url) { + // If the renderer was not passed the switch to enable native workers, + // then the URL should be treated as a JavaScript worker. + if (!CommandLine::ForCurrentProcess()->HasSwitch( + switches::kEnableNativeWebWorkers)) { + return false; + } + // Based on the suffix, decide whether the url should be considered + // a NativeWebWorker (for .nexe) or a WebWorker (for anything else). + const std::string kNativeSuffix(".nexe"); + std::string worker_url = url.path(); + // Compute the start index of the suffix. + std::string::size_type suffix_index = + worker_url.length() - kNativeSuffix.length(); + std::string::size_type pos = worker_url.find(kNativeSuffix, suffix_index); + return (suffix_index == pos); +} + WebWorkerClientProxy::WebWorkerClientProxy(const GURL& url, int route_id) : url_(url), - route_id_(route_id), - ALLOW_THIS_IN_INITIALIZER_LIST(impl_(WebWorker::create(this))) { + route_id_(route_id) { + if (UrlIsNativeWorker(url)) { + // Launch a native worker. + impl_ = NativeWebWorkerImpl::create(this); + } else { + // Launch a JavaScript worker. + impl_ = WebWorker::create(this); + } WorkerThread::current()->AddRoute(route_id_, this); ChildProcess::current()->AddRefProcess(); } |