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

Side by Side Diff: ppapi/proxy/enter_proxy.h

Issue 7585025: Reland 95309. Add a template to handle properly issuing completion callbacks. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 9 years, 4 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « ppapi/ppapi_shared.gypi ('k') | ppapi/proxy/ppb_audio_proxy.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #ifndef PPAPI_PROXY_ENTER_PROXY_H_ 5 #ifndef PPAPI_PROXY_ENTER_PROXY_H_
6 #define PPAPI_PROXY_ENTER_PROXY_H_ 6 #define PPAPI_PROXY_ENTER_PROXY_H_
7 7
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "ppapi/cpp/completion_callback.h"
9 #include "ppapi/proxy/host_dispatcher.h" 10 #include "ppapi/proxy/host_dispatcher.h"
10 #include "ppapi/proxy/plugin_dispatcher.h" 11 #include "ppapi/proxy/plugin_dispatcher.h"
11 #include "ppapi/proxy/plugin_resource_tracker.h" 12 #include "ppapi/proxy/plugin_resource_tracker.h"
12 #include "ppapi/thunk/enter.h" 13 #include "ppapi/thunk/enter.h"
13 14
14 namespace pp { 15 namespace pp {
15 namespace proxy { 16 namespace proxy {
16 17
17 // Wrapper around EnterResourceNoLock that takes a host resource. This is used 18 // Wrapper around EnterResourceNoLock that takes a host resource. This is used
18 // when handling messages in the plugin from the host and we need to convert to 19 // when handling messages in the plugin from the host and we need to convert to
(...skipping 26 matching lines...) Expand all
45 : ::ppapi::thunk::EnterResourceNoLock<ResourceT>( 46 : ::ppapi::thunk::EnterResourceNoLock<ResourceT>(
46 host_resource.host_resource(), false) { 47 host_resource.host_resource(), false) {
47 // Validate that we're in the host rather than the plugin. Otherwise this 48 // Validate that we're in the host rather than the plugin. Otherwise this
48 // object will do the wrong thing. In the host, the instance should have 49 // object will do the wrong thing. In the host, the instance should have
49 // a corresponding host disptacher (assuming the resource is valid). 50 // a corresponding host disptacher (assuming the resource is valid).
50 DCHECK(this->failed() || 51 DCHECK(this->failed() ||
51 HostDispatcher::GetForInstance(host_resource.instance())); 52 HostDispatcher::GetForInstance(host_resource.instance()));
52 } 53 }
53 }; 54 };
54 55
56 // Enters a resource and forces a completion callback to be issued.
57 //
58 // This is used when implementing the host (renderer) side of a resource
59 // function that issues a completion callback. In all cases, we need to issue
60 // the callback to avoid hanging the plugin.
61 //
62 // This class automatically constructs a callback with the given factory
63 // calling the given method. The method will generally be the one that sends
64 // the message to trigger the completion callback in the plugin process.
65 //
66 // It will automatically issue the callback with PP_ERROR_NOINTERFACE if the
67 // host resource is invalid (i.e. failed() is set). In all other cases you
68 // should call SetResult(), which will issue the callback immediately if the
69 // result value isn't PP_OK_COMPLETIONPENDING. In the "completion pending"
70 // case, it's assumed the function the proxy is calling will take responsibility
71 // of executing the callback (returned by callback()).
72 //
73 // Example:
74 // EnterHostFromHostResourceForceCallback<PPB_Foo_API> enter(
75 // resource, callback_factory_, &MyClass::SendResult, resource);
76 // if (enter.failed())
77 // return; // SendResult automatically called with PP_ERROR_BADRESOURCE.
78 // enter.SetResult(enter.object()->DoFoo(enter.callback()));
79 //
80 // Where DoFoo's signature looks like this:
81 // int32_t DoFoo(PP_CompletionCallback callback);
82 // And SendResult's implementation looks like this:
83 // void MyClass::SendResult(int32_t result, const HostResource& res) {
84 // Send(new FooMsg_FooComplete(..., result, res));
85 // }
86 template<typename ResourceT>
87 class EnterHostFromHostResourceForceCallback
88 : public EnterHostFromHostResource<ResourceT> {
89 public:
90 // For callbacks that take no parameters except the "int32_t result". Most
91 // implementations will use the 1-extra-argument constructor below.
92 template<class CallbackFactory, typename Method>
93 EnterHostFromHostResourceForceCallback(const HostResource& host_resource,
94 CallbackFactory& factory,
95 Method method)
96 : EnterHostFromHostResource<ResourceT>(host_resource),
97 needs_running_(true),
98 callback_(factory.NewOptionalCallback(method)) {
99 if (this->failed())
100 RunCallback(PP_ERROR_BADRESOURCE);
101 }
102
103 // For callbacks that take an extra parameter as a closure.
104 template<class CallbackFactory, typename Method, typename A>
105 EnterHostFromHostResourceForceCallback(const HostResource& host_resource,
106 CallbackFactory& factory,
107 Method method,
108 const A& a)
109 : EnterHostFromHostResource<ResourceT>(host_resource),
110 needs_running_(true),
111 callback_(factory.NewOptionalCallback(method, a)) {
112 if (this->failed())
113 RunCallback(PP_ERROR_BADRESOURCE);
114 }
115
116 ~EnterHostFromHostResourceForceCallback() {
117 if (needs_running_) {
118 NOTREACHED() << "Should always call SetResult except in the "
119 "initialization failed case.";
120 RunCallback(PP_ERROR_FAILED);
121 }
122 }
123
124 void SetResult(int32_t result) {
125 DCHECK(needs_running_) << "Don't call SetResult when there already is one.";
126 needs_running_ = false;
127 if (result != PP_OK_COMPLETIONPENDING)
128 callback_.Run(result);
129 }
130
131 PP_CompletionCallback callback() {
132 return callback_.pp_completion_callback();
133 }
134
135 private:
136 void RunCallback(int32_t result) {
137 DCHECK(needs_running_);
138 needs_running_ = false;
139 callback_.Run(result);
140 }
141
142 bool needs_running_;
143 pp::CompletionCallback callback_;
144 };
145
55 } // namespace proxy 146 } // namespace proxy
56 } // namespace pp 147 } // namespace pp
57 148
58 #endif // PPAPI_PROXY_ENTER_PROXY_H_ 149 #endif // PPAPI_PROXY_ENTER_PROXY_H_
OLDNEW
« no previous file with comments | « ppapi/ppapi_shared.gypi ('k') | ppapi/proxy/ppb_audio_proxy.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698