Index: ppapi/proxy/enter_proxy.h |
=================================================================== |
--- ppapi/proxy/enter_proxy.h (revision 106763) |
+++ ppapi/proxy/enter_proxy.h (working copy) |
@@ -166,6 +166,82 @@ |
pp::CompletionCallback callback_; |
}; |
+// Like EnterHostFromHostResourceForceCallback but for Function APIs. It takes |
+// an instance instead of a resource ID. |
+template<typename FunctionT> |
+class EnterHostFunctionForceCallback |
+ : public thunk::EnterFunctionNoLock<FunctionT> { |
+ public: |
+ // For callbacks that take no parameters except the "int32_t result". Most |
+ // implementations will use the 1-extra-argument constructor below. |
+ template<class CallbackFactory, typename Method> |
+ EnterHostFunctionForceCallback(PP_Instance instance, |
+ CallbackFactory& factory, |
+ Method method) |
+ : thunk::EnterFunctionNoLock<FunctionT>(instance, false), |
+ needs_running_(true), |
+ callback_(factory.NewOptionalCallback(method)) { |
+ if (this->failed()) |
+ RunCallback(PP_ERROR_BADARGUMENT); |
+ } |
+ |
+ // For callbacks that take an extra parameter as a closure. |
+ template<class CallbackFactory, typename Method, typename A> |
+ EnterHostFunctionForceCallback(PP_Instance instance, |
+ CallbackFactory& factory, |
+ Method method, |
+ const A& a) |
+ : thunk::EnterFunctionNoLock<FunctionT>(instance, false), |
+ needs_running_(true), |
+ callback_(factory.NewOptionalCallback(method, a)) { |
+ if (this->failed()) |
+ RunCallback(PP_ERROR_BADARGUMENT); |
+ } |
+ |
+ // For callbacks that take two extra parameters as a closure. |
+ template<class CallbackFactory, typename Method, typename A, typename B> |
+ EnterHostFunctionForceCallback(PP_Instance instance, |
+ CallbackFactory& factory, |
+ Method method, |
+ const A& a, |
+ const B& b) |
+ : thunk::EnterFunctionNoLock<FunctionT>(instance), |
+ needs_running_(true), |
+ callback_(factory.NewOptionalCallback(method, a, b)) { |
+ if (this->failed()) |
+ RunCallback(PP_ERROR_BADARGUMENT); |
+ } |
+ |
+ ~EnterHostFunctionForceCallback() { |
+ if (needs_running_) { |
+ NOTREACHED() << "Should always call SetResult except in the " |
+ "initialization failed case."; |
+ RunCallback(PP_ERROR_FAILED); |
+ } |
+ } |
+ |
+ void SetResult(int32_t result) { |
+ DCHECK(needs_running_) << "Don't call SetResult when there already is one."; |
+ needs_running_ = false; |
+ if (result != PP_OK_COMPLETIONPENDING) |
+ callback_.Run(result); |
+ } |
+ |
+ PP_CompletionCallback callback() { |
+ return callback_.pp_completion_callback(); |
+ } |
+ |
+ private: |
+ void RunCallback(int32_t result) { |
+ DCHECK(needs_running_); |
+ needs_running_ = false; |
+ callback_.Run(result); |
+ } |
+ |
+ bool needs_running_; |
+ pp::CompletionCallback callback_; |
+}; |
+ |
} // namespace proxy |
} // namespace ppapi |