summaryrefslogtreecommitdiffstats
path: root/chrome/worker
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/worker')
-rw-r--r--chrome/worker/nativewebworker_impl.cc159
-rw-r--r--chrome/worker/nativewebworker_impl.h44
-rw-r--r--chrome/worker/nativewebworker_stub.cc46
-rw-r--r--chrome/worker/nativewebworker_stub.h63
-rw-r--r--chrome/worker/webworkerclient_proxy.cc29
5 files changed, 339 insertions, 2 deletions
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();
}