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

Unified Diff: ppapi/thunk/enter.h

Issue 10081020: PPAPI: Make blocking completion callbacks work. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Updated TestURLLoader to test blocking callbacks. Created 8 years, 8 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/thunk/enter.h
diff --git a/ppapi/thunk/enter.h b/ppapi/thunk/enter.h
index 4172ce0e60b2863769946ee87e00ab866687742b..5105a8b757964cc29105c837291b9e89aaa9cff5 100644
--- a/ppapi/thunk/enter.h
+++ b/ppapi/thunk/enter.h
@@ -5,7 +5,12 @@
#ifndef PPAPI_THUNK_ENTER_H_
#define PPAPI_THUNK_ENTER_H_
+#include <string>
+
#include "base/basictypes.h"
+#include "base/memory/ref_counted.h"
+#include "base/synchronization/lock.h"
+#include "ppapi/c/pp_errors.h"
#include "ppapi/c/pp_resource.h"
#include "ppapi/shared_impl/api_id.h"
#include "ppapi/shared_impl/function_group_base.h"
@@ -18,6 +23,8 @@
#include "ppapi/thunk/resource_creation_api.h"
namespace ppapi {
+class TrackedCallback;
+
namespace thunk {
// Enter* helper objects: These objects wrap a call from the C PPAPI into
@@ -53,7 +60,23 @@ struct LockOnEntry;
template <>
struct LockOnEntry<false> {
-// TODO(dmichael) assert the lock is held.
+#if (!NDEBUG)
+ LockOnEntry() {
+ // You must already hold the lock to use Enter*NoLock.
+ AssertLockHeld();
+ }
+ ~LockOnEntry() {
+ // You must not release the lock before leaving the scope of the
+ // Enter*NoLock.
+ AssertLockHeld();
+ }
+ private:
+ static void AssertLockHeld() {
+ base::Lock* proxy_lock = PpapiGlobals::Get()->GetProxyLock();
+ if (proxy_lock)
+ proxy_lock->AssertAcquired();
+ }
+#endif
};
template <>
@@ -70,10 +93,15 @@ struct LockOnEntry<true> {
class PPAPI_THUNK_EXPORT EnterBase {
public:
EnterBase();
- explicit EnterBase(const PP_CompletionCallback& callback);
+ explicit EnterBase(PP_Resource resource);
+ EnterBase(PP_Resource resource, const PP_CompletionCallback& callback);
virtual ~EnterBase();
- // Sets the result.
+ // Sets the result for calls that use a completion callback. It handles making
+ // sure that "Required" callbacks are scheduled to run asynchronously and
+ // "Blocking" callbacks cause the caller to block. (Interface implementations,
+ // therefore, should not do any special casing based on the type of the
+ // callback.)
//
// Returns the "retval()". This is to support the typical usage of
// return enter.SetResult(...);
@@ -83,6 +111,11 @@ class PPAPI_THUNK_EXPORT EnterBase {
// Use this value as the return value for the function.
int32_t retval() const { return retval_; }
+ bool succeeded() const { return retval_ == PP_OK; }
+ bool failed() const { return !succeeded(); }
+
+ const scoped_refptr<TrackedCallback>& callback() { return callback_; }
+
protected:
// Helper function to return a function group from a PP_Instance. Having this
// code be in the non-templatized base keeps us from having to instantiate
@@ -92,14 +125,21 @@ class PPAPI_THUNK_EXPORT EnterBase {
// Helper function to return a Resource from a PP_Resource. Having this
// code be in the non-templatized base keeps us from having to instantiate
// it in every template.
- Resource* GetResource(PP_Resource resource) const;
+ static Resource* GetResource(PP_Resource resource);
+
+ // Checks whether the callback is valid (i.e., if it is either non-blocking,
+ // or blocking and we're on a background thread). If the callback is invalid,
+ // this will set retval_ = PP_ERROR_BLOCKS_MAIN_THREAD, and if report_error is
+ // set, it will log a message to the programmer.
+ void SetStateForCallbackError(bool report_error);
+ bool CallbackIsValid() const;
// Does error handling associated with entering a resource. The resource_base
// is the result of looking up the given pp_resource. The object is the
- // result of converting the base to the desired object (converted back to a
- // Resource* so this function doesn't have to be templatized). The reason for
- // passing both resource_base and object is that we can differentiate "bad
- // resource ID" from "valid resource ID not of the currect type."
+ // result of converting the base to the desired object (converted to a void*
+ // so this function doesn't have to be templatized). The reason for passing
+ // both resource_base and object is that we can differentiate "bad resource
+ // ID" from "valid resource ID not of the correct type."
//
// This will set retval_ = PP_ERROR_BADRESOURCE if the object is invalid, and
// if report_error is set, log a message to the programmer.
@@ -113,11 +153,15 @@ class PPAPI_THUNK_EXPORT EnterBase {
void* object,
bool report_error);
+ // For Enter objects that need a resource, we'll store a pointer to the
+ // Resource object so that we don't need to look it up more than once. For
+ // Enter objects with no resource, this will be NULL.
+ Resource* resource_;
+
private:
- // Holds the callback. The function will only be non-NULL when the
- // callback is requried. Optional callbacks don't require any special
- // handling from us at this layer.
- PP_CompletionCallback callback_;
+ // Holds the callback. For Enter objects that aren't given a callback, this
+ // will be NULL.
+ scoped_refptr<TrackedCallback> callback_;
int32_t retval_;
};
@@ -131,20 +175,23 @@ class EnterFunction : public subtle::EnterBase,
public subtle::LockOnEntry<lock_on_entry> {
public:
EnterFunction(PP_Instance instance, bool report_error)
- : EnterBase() {
+ : EnterBase(instance) {
Init(instance, report_error);
}
EnterFunction(PP_Instance instance,
const PP_CompletionCallback& callback,
bool report_error)
- : EnterBase(callback) {
+ : EnterBase(0 /* resource */, callback) {
+ // TODO(dmichael): This means that the callback_ we get is not associated
+ // even with the instance, but we need to handle that for
+ // MouseLock (maybe others?).
Init(instance, report_error);
}
~EnterFunction() {}
- bool succeeded() const { return !!functions_; }
- bool failed() const { return !functions_; }
+/* bool succeeded() const { return !!functions_ && CallbackIsValid(); }
+ bool failed() const { return !succeeded(); }*/
FunctionsT* functions() { return functions_; }
@@ -155,6 +202,10 @@ class EnterFunction : public subtle::EnterBase,
functions_ = base->GetAs<FunctionsT>();
else
functions_ = NULL;
+ // Validate the callback.
+ SetStateForCallbackError(report_error);
+ // Validate the resource (note, if both are wrong, we will return
+ // PP_ERROR_BADARGUMENT; last in wins).
SetStateForFunctionError(instance, functions_, report_error);
}
@@ -184,8 +235,7 @@ class EnterFunctionGivenResource : public EnterFunction<FunctionsT> {
private:
static PP_Instance GetInstanceForResource(PP_Resource resource) {
- Resource* object =
- PpapiGlobals::Get()->GetResourceTracker()->GetResource(resource);
+ Resource* object = subtle::EnterBase::GetResource(resource);
return object ? object->pp_instance() : 0;
}
};
@@ -197,34 +247,35 @@ class EnterResource : public subtle::EnterBase,
public subtle::LockOnEntry<lock_on_entry> {
public:
EnterResource(PP_Resource resource, bool report_error)
- : EnterBase() {
+ : EnterBase(resource) {
Init(resource, report_error);
}
- EnterResource(PP_Resource resource,
- const PP_CompletionCallback& callback,
+ EnterResource(PP_Resource resource, const PP_CompletionCallback& callback,
bool report_error)
- : EnterBase(callback) {
+ : EnterBase(resource, callback) {
Init(resource, report_error);
}
~EnterResource() {}
- bool succeeded() const { return !!object_; }
- bool failed() const { return !object_; }
+/* bool succeeded() const { return !!object_ && CallbackIsValid(); }
+ bool failed() const { return !succeeded(); }*/
ResourceT* object() { return object_; }
Resource* resource() { return resource_; }
private:
void Init(PP_Resource resource, bool report_error) {
- resource_ = GetResource(resource);
if (resource_)
object_ = resource_->GetAs<ResourceT>();
else
object_ = NULL;
+ // Validate the callback.
+ SetStateForCallbackError(report_error);
+ // Validate the resource (note, if both are wrong, we will return
+ // PP_ERROR_BADRESOURCE; last in wins).
SetStateForResourceError(resource, resource_, object_, report_error);
}
- Resource* resource_;
ResourceT* object_;
DISALLOW_COPY_AND_ASSIGN(EnterResource);
@@ -239,6 +290,10 @@ class EnterResourceNoLock : public EnterResource<ResourceT, false> {
EnterResourceNoLock(PP_Resource resource, bool report_error)
: EnterResource<ResourceT, false>(resource, report_error) {
}
+ EnterResourceNoLock(PP_Resource resource, PP_CompletionCallback callback,
+ bool report_error)
+ : EnterResource<ResourceT, false>(resource, callback, report_error) {
+ }
};
// Simpler wrapper to enter the resource creation API. This is used for every
@@ -262,6 +317,16 @@ class PPAPI_THUNK_EXPORT EnterInstance
~EnterInstance();
};
dmichael (off chromium) 2012/04/19 20:02:00 I needed EnterInstanceNoLock to make AudioConfigSh
+class PPAPI_THUNK_EXPORT EnterInstanceNoLock
+ : public EnterFunctionNoLock<PPB_Instance_FunctionAPI> {
+ public:
+ EnterInstanceNoLock(PP_Instance instance);
+ EnterInstanceNoLock(PP_Instance instance,
+ const PP_CompletionCallback& callback);
+ ~EnterInstanceNoLock();
+};
+
+
} // namespace thunk
} // namespace ppapi

Powered by Google App Engine
This is Rietveld 408576698