Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(453)

Unified Diff: ppapi/native_client/src/untrusted/nacl_ppapi_util/nacl_ppapi_util.h

Issue 10914053: Relocating files in the nacl repo that belong in chrome. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: merge Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: ppapi/native_client/src/untrusted/nacl_ppapi_util/nacl_ppapi_util.h
diff --git a/ppapi/native_client/src/untrusted/nacl_ppapi_util/nacl_ppapi_util.h b/ppapi/native_client/src/untrusted/nacl_ppapi_util/nacl_ppapi_util.h
new file mode 100644
index 0000000000000000000000000000000000000000..f98baa45467b505b61a9eec18106442a65d573eb
--- /dev/null
+++ b/ppapi/native_client/src/untrusted/nacl_ppapi_util/nacl_ppapi_util.h
@@ -0,0 +1,202 @@
+/* -*- c++ -*- */
+/*
+ * Copyright (c) 2011 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 NATIVE_CLIENT_SRC_UNTRUSTED_NACL_PPAPI_UTIL_NACL_PPAPI_UTIL_H_
+#define NATIVE_CLIENT_SRC_UNTRUSTED_NACL_PPAPI_UTIL_NACL_PPAPI_UTIL_H_
+
+#include "ppapi/cpp/instance.h"
+#include "ppapi/cpp/module.h"
+#include "ppapi/cpp/var.h"
+
+#include "native_client/src/include/nacl_base.h"
+#include "native_client/src/include/nacl_scoped_ptr.h"
+#include "native_client/src/shared/platform/nacl_sync.h"
+#include "native_client/src/shared/platform/nacl_sync_checked.h"
+#include "native_client/src/shared/platform/nacl_sync_raii.h"
+
+// TODO(bsy): move weak_ref module to the shared directory
+#include "native_client/src/trusted/weak_ref/weak_ref.h"
+#include "native_client/src/trusted/weak_ref/call_on_main_thread.h"
+
+// The nomenclature used in this file is intended to clarify thinking
+// about the Pepper "main thread". The "main thread" is really an
+// interrupt service thread, or an event handler thread, since it is
+// bad to do blocking operations or execute code that runs for a long
+// time on it. Event handlers should complete quickly -- possibly
+// just enqueuing the event for processing by some worker thread --
+// and return, so that additional event dispatch can occur.
+
+// Code that does real work (and tests) should run in a separate,
+// worker thread. The main event handler thread is where the
+// post-message handler runs via a pp::Module virtual member function
+// (HandleMessage), which represents the plugin instance. This plugin
+// instance can go away at any time, e.g., due to surf-away. Thus,
+// other threads should not use pointers to the pp::Module, since the
+// object isn't reference counted (and probably shouldn't be, since
+// it really have to shut down / clean up when Pepper tells it to),
+// and main thread-only operations such as PostMessage or
+// GetOSFileDescriptor on the FileIO_Dev PP_Resource must not be done
+// from the worker threads.
+
+// Our solution to this is as follows:
+//
+// The plugin instance object holds a reference to a WeakRefAnchor
+// object, and the plugin instance object's dtor invokes the Abandon
+// method on the anchor. Since the nacl::WeakRefAnchor object is
+// thread-safe and is reference counted, the anchor pointer may be
+// passed to worker threads. Worker threads are responsible for
+// maintaining the anchor refcount: each thread would hold a
+// reference, and must Unref prior to thread exit. The worker threads
+// can use plugin::WeakRefCallOnMainThread to enqueue continuation
+// callbacks to run on the main thread -- these will get cancelled if
+// the WeakRefAnchor was abandoned, which only occurs in the module
+// object's dtor, which can only run in the main thread. Since the
+// continuation won't run if the plugin instance is still valid, the
+// continuation can safely use pointers to the instance to perform
+// main-thread operations or to run member functions in the test
+// object or in the module object. The worker thread may hold a
+// pointer to the plugin instance object in order to schedule
+// callbacks via plugin::WeakRefCallOnMainThread using a method
+// pointer, but should not otherwise use the pointer.
+//
+// So, an operation (test) running on a worker thread must be broken
+// into separate computation phases according to which thread is
+// appropriate for invoking which operations. For compute-only phases
+// or manifest RPCs (which block and also invoke CallOnMainThread),
+// the computation should occur on the worker thread. When the worker
+// thread needs to invoke a main-thread-only operation such as
+// PostMessage, it should use its WeakRefAnchor objecct to schedule a
+// main thread callback and then wait on a condition variable for the
+// operation to complete. The main thread callback can invoke the
+// main-thread-only operation, then signal the condition variable to
+// wake up the worker thread prior to returning. After the worker
+// thread wakes up, it can use other synchronization methods to
+// determine if the worker thread should continue to run or exit
+// (e.g., if the worker thread is associated with the plugin instance,
+// then if the main thread work result is NULL, the worker thread
+// should probably Unref its anchor (and do other cleanup) and exit.
+
+namespace nacl_ppapi {
+
+template <typename R> class EventThreadWorkStateWrapper; // fwd
+
+// the worker thread should own the EventThreadWorkState<R> object
+template <typename R>
+class EventThreadWorkState {
+ public:
+ EventThreadWorkState()
+ : done_(false),
+ result_(NULL) {
+ NaClXMutexCtor(&mu_);
+ NaClXCondVarCtor(&cv_);
+ }
+
+ virtual ~EventThreadWorkState() {
+ NaClMutexDtor(&mu_);
+ NaClCondVarDtor(&cv_);
+ }
+
+ // Pass ownership of result into the EventThreadWorkState. The value
+ // of result should be non-NULL to distinguish between
+ // completion/abandonment.
+ void SetResult(R *result) {
+ nacl::MutexLocker take(&mu_);
+ result_.reset(result);
+ }
+
+ // Returns result if callback completed, NULL if abandoned
+ R *WaitForCompletion() {
+ nacl::MutexLocker take(&mu_);
+ while (!done_) {
+ NaClXCondVarWait(&cv_, &mu_);
+ }
+ return result_.release();
+ }
+
+ private:
+ friend class EventThreadWorkStateWrapper<R>;
+ void EventThreadWorkDone() {
+ nacl::MutexLocker take(&mu_);
+ done_ = true;
+ NaClXCondVarBroadcast(&cv_);
+ }
+
+ NaClMutex mu_;
+ NaClCondVar cv_;
+ bool done_;
+ nacl::scoped_ptr<R> result_;
+
+ DISALLOW_COPY_AND_ASSIGN(EventThreadWorkState);
+};
+
+
+// Wrapper around EventThreadWorkState<R> or subclass thereof. The
+// wrapper object should be created by a worker thread and the
+// ownership passed into the COMT machinery, to be used and deleted on
+// the main thread. This object is automatically deleted by the
+// WeakRef machinery when the callback fires, and the dtor will just
+// signal completion. If the anchor corresponding to the callback had
+// not been abandoned, then the callback function should invoke
+// SetResult before returning to pass ownership of a result object (R)
+// from the main thread to the worker thread.
+//
+// Subclasses of EventThreadWorkStateWrapper may be used, so that
+// contained input arguments are automatically deleted when the
+// callback fires, or input arguments may be stashed in subclasses of
+// EventThreadWorkState<R>.
+template <typename R>
+class EventThreadWorkStateWrapper {
+ public:
+ explicit EventThreadWorkStateWrapper(EventThreadWorkState<R> *ws):
+ ws_(ws) {}
+ virtual ~EventThreadWorkStateWrapper() {
+ ws_->EventThreadWorkDone();
+ };
+
+ void SetResult(R *result) {
+ ws_->SetResult(result);
+ }
+ private:
+ EventThreadWorkState<R> *ws_;
+
+ DISALLOW_COPY_AND_ASSIGN(EventThreadWorkStateWrapper);
+};
+
+class VoidResult;
+
+extern VoidResult *const g_void_result;
+
+class VoidResult {
+ public:
+ VoidResult() {}
+ void *operator new(size_t size) { return g_void_result; }
+ void operator delete(void *p) {}
+ private:
+ DISALLOW_COPY_AND_ASSIGN(VoidResult);
+};
+
+// Canonical pointer return value used with SetResult when the main
+// thread operation does not return a result. The class declaration
+// is private, so the compiler should refuse to allow the use of the
+// delete operator.
+
+// A plugin instance object should be referred to only from the main
+// thread. Pointers to the anchor object can be given to worker
+// thread so they can schedule work on the main thread via COMT.
+class NaClPpapiPluginInstance : public pp::Instance {
+ public:
+ explicit NaClPpapiPluginInstance(PP_Instance instance);
+ virtual ~NaClPpapiPluginInstance();
+ nacl::WeakRefAnchor* anchor() const { return anchor_; }
+ protected:
+ nacl::WeakRefAnchor* anchor_;
+ DISALLOW_COPY_AND_ASSIGN(NaClPpapiPluginInstance);
+};
+
+} // namespace nacl_ppapi
+
+#endif

Powered by Google App Engine
This is Rietveld 408576698