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

Side by Side Diff: ppapi/proxy/ppb_file_ref_proxy.cc

Issue 8226009: Remove the proxy callback tracker. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: PostMessage define. Created 9 years, 2 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
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 #include "ppapi/proxy/ppb_file_ref_proxy.h" 5 #include "ppapi/proxy/ppb_file_ref_proxy.h"
6 6
7 #include <map>
8
9 #include "base/bind.h"
7 #include "ppapi/c/pp_errors.h" 10 #include "ppapi/c/pp_errors.h"
8 #include "ppapi/c/ppb_file_ref.h" 11 #include "ppapi/c/ppb_file_ref.h"
9 #include "ppapi/c/private/ppb_proxy_private.h" 12 #include "ppapi/c/private/ppb_proxy_private.h"
10 #include "ppapi/proxy/enter_proxy.h" 13 #include "ppapi/proxy/enter_proxy.h"
11 #include "ppapi/proxy/host_dispatcher.h" 14 #include "ppapi/proxy/host_dispatcher.h"
12 #include "ppapi/proxy/plugin_dispatcher.h" 15 #include "ppapi/proxy/plugin_dispatcher.h"
13 #include "ppapi/proxy/ppapi_messages.h" 16 #include "ppapi/proxy/ppapi_messages.h"
14 #include "ppapi/proxy/serialized_var.h" 17 #include "ppapi/proxy/serialized_var.h"
15 #include "ppapi/shared_impl/file_ref_impl.h" 18 #include "ppapi/shared_impl/file_ref_impl.h"
16 #include "ppapi/thunk/resource_creation_api.h" 19 #include "ppapi/thunk/resource_creation_api.h"
(...skipping 16 matching lines...) Expand all
33 virtual PP_Resource GetParent() OVERRIDE; 36 virtual PP_Resource GetParent() OVERRIDE;
34 virtual int32_t MakeDirectory(PP_Bool make_ancestors, 37 virtual int32_t MakeDirectory(PP_Bool make_ancestors,
35 PP_CompletionCallback callback) OVERRIDE; 38 PP_CompletionCallback callback) OVERRIDE;
36 virtual int32_t Touch(PP_Time last_access_time, 39 virtual int32_t Touch(PP_Time last_access_time,
37 PP_Time last_modified_time, 40 PP_Time last_modified_time,
38 PP_CompletionCallback callback) OVERRIDE; 41 PP_CompletionCallback callback) OVERRIDE;
39 virtual int32_t Delete(PP_CompletionCallback callback) OVERRIDE; 42 virtual int32_t Delete(PP_CompletionCallback callback) OVERRIDE;
40 virtual int32_t Rename(PP_Resource new_file_ref, 43 virtual int32_t Rename(PP_Resource new_file_ref,
41 PP_CompletionCallback callback) OVERRIDE; 44 PP_CompletionCallback callback) OVERRIDE;
42 45
46 // Executes the pending callback with the given ID. See pending_callbacks_.
47 void ExecuteCallback(int callback_id, int32_t result);
48
43 private: 49 private:
44 PluginDispatcher* GetDispatcher() const { 50 PluginDispatcher* GetDispatcher() const {
45 return PluginDispatcher::GetForResource(this); 51 return PluginDispatcher::GetForResource(this);
46 } 52 }
47 53
54 // Adds a callback to the list and returns its ID. Returns 0 if the callback
55 // is invalid.
56 int SendCallback(PP_CompletionCallback callback);
57
58 // This class can have any number of out-standing requests with completion
59 // callbacks, in contrast to most resources which have one possible pending
60 // callback pending (like a Flush callback).
61 //
62 // To keep track of them, assign integer IDs to the callbacks, which is how
63 // the callback will be identified when it's passed to the host and then
64 // back here.
65 int next_callback_id_;
66 typedef std::map<int, PP_CompletionCallback> PendingCallbackMap;
67 PendingCallbackMap pending_callbacks_;
68
48 DISALLOW_IMPLICIT_CONSTRUCTORS(FileRef); 69 DISALLOW_IMPLICIT_CONSTRUCTORS(FileRef);
49 }; 70 };
50 71
51 FileRef::FileRef(const PPB_FileRef_CreateInfo& info) 72 FileRef::FileRef(const PPB_FileRef_CreateInfo& info)
52 : FileRefImpl(FileRefImpl::InitAsProxy(), info) { 73 : FileRefImpl(FileRefImpl::InitAsProxy(), info),
74 next_callback_id_(0) {
53 } 75 }
54 76
55 FileRef::~FileRef() { 77 FileRef::~FileRef() {
78 // Abort all pending callbacks. Do this by posting a task to avoid reentering
79 // the plugin's Release() call that probably deleted this object.
80 for (PendingCallbackMap::iterator i = pending_callbacks_.begin();
81 i != pending_callbacks_.end(); ++i) {
82 MessageLoop::current()->PostTask(FROM_HERE, base::Bind(
83 i->second.func, i->second.user_data,
84 static_cast<int32_t>(PP_ERROR_ABORTED)));
85 }
56 } 86 }
57 87
58 PP_Resource FileRef::GetParent() { 88 PP_Resource FileRef::GetParent() {
59 PPB_FileRef_CreateInfo create_info; 89 PPB_FileRef_CreateInfo create_info;
60 GetDispatcher()->Send(new PpapiHostMsg_PPBFileRef_GetParent( 90 GetDispatcher()->Send(new PpapiHostMsg_PPBFileRef_GetParent(
61 INTERFACE_ID_PPB_FILE_REF, host_resource(), &create_info)); 91 INTERFACE_ID_PPB_FILE_REF, host_resource(), &create_info));
62 return PPB_FileRef_Proxy::DeserializeFileRef(create_info); 92 return PPB_FileRef_Proxy::DeserializeFileRef(create_info);
63 } 93 }
64 94
65 int32_t FileRef::MakeDirectory(PP_Bool make_ancestors, 95 int32_t FileRef::MakeDirectory(PP_Bool make_ancestors,
66 PP_CompletionCallback callback) { 96 PP_CompletionCallback callback) {
97 int callback_id = SendCallback(callback);
98 if (!callback_id)
99 return PP_ERROR_BADARGUMENT;
100
67 GetDispatcher()->Send(new PpapiHostMsg_PPBFileRef_MakeDirectory( 101 GetDispatcher()->Send(new PpapiHostMsg_PPBFileRef_MakeDirectory(
68 INTERFACE_ID_PPB_FILE_REF, host_resource(), make_ancestors, 102 INTERFACE_ID_PPB_FILE_REF, host_resource(), make_ancestors, callback_id));
69 GetDispatcher()->callback_tracker().SendCallback(callback)));
70 return PP_OK_COMPLETIONPENDING; 103 return PP_OK_COMPLETIONPENDING;
71 } 104 }
72 105
73 int32_t FileRef::Touch(PP_Time last_access_time, 106 int32_t FileRef::Touch(PP_Time last_access_time,
74 PP_Time last_modified_time, 107 PP_Time last_modified_time,
75 PP_CompletionCallback callback) { 108 PP_CompletionCallback callback) {
109 int callback_id = SendCallback(callback);
110 if (!callback_id)
111 return PP_ERROR_BADARGUMENT;
112
76 GetDispatcher()->Send(new PpapiHostMsg_PPBFileRef_Touch( 113 GetDispatcher()->Send(new PpapiHostMsg_PPBFileRef_Touch(
77 INTERFACE_ID_PPB_FILE_REF, host_resource(), 114 INTERFACE_ID_PPB_FILE_REF, host_resource(),
78 last_access_time, last_modified_time, 115 last_access_time, last_modified_time, callback_id));
79 GetDispatcher()->callback_tracker().SendCallback(callback)));
80 return PP_OK_COMPLETIONPENDING; 116 return PP_OK_COMPLETIONPENDING;
81 } 117 }
82 118
83 int32_t FileRef::Delete(PP_CompletionCallback callback) { 119 int32_t FileRef::Delete(PP_CompletionCallback callback) {
120 int callback_id = SendCallback(callback);
121 if (!callback_id)
122 return PP_ERROR_BADARGUMENT;
123
84 GetDispatcher()->Send(new PpapiHostMsg_PPBFileRef_Delete( 124 GetDispatcher()->Send(new PpapiHostMsg_PPBFileRef_Delete(
85 INTERFACE_ID_PPB_FILE_REF, host_resource(), 125 INTERFACE_ID_PPB_FILE_REF, host_resource(), callback_id));
86 GetDispatcher()->callback_tracker().SendCallback(callback)));
87 return PP_OK_COMPLETIONPENDING; 126 return PP_OK_COMPLETIONPENDING;
88 } 127 }
89 128
90 int32_t FileRef::Rename(PP_Resource new_file_ref, 129 int32_t FileRef::Rename(PP_Resource new_file_ref,
91 PP_CompletionCallback callback) { 130 PP_CompletionCallback callback) {
131 int callback_id = SendCallback(callback);
132 if (!callback_id)
133 return PP_ERROR_BADARGUMENT;
134
92 Resource* new_file_ref_object = 135 Resource* new_file_ref_object =
93 PluginResourceTracker::GetInstance()->GetResource(new_file_ref); 136 PluginResourceTracker::GetInstance()->GetResource(new_file_ref);
94 if (!new_file_ref_object || 137 if (!new_file_ref_object ||
95 new_file_ref_object->host_resource().instance() != pp_instance()) 138 new_file_ref_object->host_resource().instance() != pp_instance())
96 return PP_ERROR_BADRESOURCE; 139 return PP_ERROR_BADRESOURCE;
97 140
98 GetDispatcher()->Send(new PpapiHostMsg_PPBFileRef_Rename( 141 GetDispatcher()->Send(new PpapiHostMsg_PPBFileRef_Rename(
99 INTERFACE_ID_PPB_FILE_REF, host_resource(), 142 INTERFACE_ID_PPB_FILE_REF, host_resource(),
100 new_file_ref_object->host_resource(), 143 new_file_ref_object->host_resource(), callback_id));
101 GetDispatcher()->callback_tracker().SendCallback(callback)));
102 return PP_OK_COMPLETIONPENDING; 144 return PP_OK_COMPLETIONPENDING;
103 } 145 }
104 146
147 void FileRef::ExecuteCallback(int callback_id, int32_t result) {
148 PendingCallbackMap::iterator found = pending_callbacks_.find(callback_id);
149 if (found == pending_callbacks_.end()) {
150 // This will happen when the plugin deletes its resource with a pending
151 // callback. The callback will be locally issued with an ABORTED call while
152 // the operation may still be pending in the renderer.
153 return;
154 }
155
156 // Executing the callback may mutate the callback list.
157 PP_CompletionCallback callback = found->second;
158 pending_callbacks_.erase(found);
159 PP_RunCompletionCallback(&callback, result);
160 }
161
162 int FileRef::SendCallback(PP_CompletionCallback callback) {
163 if (!callback.func)
164 return 0;
165
166 // In extreme cases the IDs may wrap around, so avoid duplicates.
167 while (pending_callbacks_.find(next_callback_id_) != pending_callbacks_.end())
168 next_callback_id_++;
169
170 pending_callbacks_[next_callback_id_] = callback;
171 return next_callback_id_++;
172 }
173
105 PPB_FileRef_Proxy::PPB_FileRef_Proxy(Dispatcher* dispatcher) 174 PPB_FileRef_Proxy::PPB_FileRef_Proxy(Dispatcher* dispatcher)
106 : InterfaceProxy(dispatcher) { 175 : InterfaceProxy(dispatcher),
176 callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
107 } 177 }
108 178
109 PPB_FileRef_Proxy::~PPB_FileRef_Proxy() { 179 PPB_FileRef_Proxy::~PPB_FileRef_Proxy() {
110 } 180 }
111 181
112 // static 182 // static
113 PP_Resource PPB_FileRef_Proxy::CreateProxyResource(PP_Resource file_system, 183 PP_Resource PPB_FileRef_Proxy::CreateProxyResource(PP_Resource file_system,
114 const char* path) { 184 const char* path) {
115 Resource* file_system_object = 185 Resource* file_system_object =
116 PluginResourceTracker::GetInstance()->GetResource(file_system); 186 PluginResourceTracker::GetInstance()->GetResource(file_system);
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
170 240
171 void PPB_FileRef_Proxy::OnMsgGetParent(const HostResource& host_resource, 241 void PPB_FileRef_Proxy::OnMsgGetParent(const HostResource& host_resource,
172 PPB_FileRef_CreateInfo* result) { 242 PPB_FileRef_CreateInfo* result) {
173 EnterHostFromHostResource<PPB_FileRef_API> enter(host_resource); 243 EnterHostFromHostResource<PPB_FileRef_API> enter(host_resource);
174 if (enter.succeeded()) 244 if (enter.succeeded())
175 SerializeFileRef(enter.object()->GetParent(), result); 245 SerializeFileRef(enter.object()->GetParent(), result);
176 } 246 }
177 247
178 void PPB_FileRef_Proxy::OnMsgMakeDirectory(const HostResource& host_resource, 248 void PPB_FileRef_Proxy::OnMsgMakeDirectory(const HostResource& host_resource,
179 PP_Bool make_ancestors, 249 PP_Bool make_ancestors,
180 uint32_t serialized_callback) { 250 int callback_id) {
181 EnterHostFromHostResource<PPB_FileRef_API> enter(host_resource); 251 EnterHostFromHostResourceForceCallback<PPB_FileRef_API> enter(
182 if (enter.failed()) 252 host_resource, callback_factory_,
183 return; 253 &PPB_FileRef_Proxy::OnCallbackCompleteInHost, host_resource, callback_id);
184 PP_CompletionCallback callback = ReceiveCallback(serialized_callback); 254 if (enter.succeeded()) {
185 int32_t result = enter.object()->MakeDirectory(make_ancestors, callback); 255 enter.SetResult(enter.object()->MakeDirectory(make_ancestors,
186 if (result != PP_OK_COMPLETIONPENDING) 256 enter.callback()));
187 PP_RunCompletionCallback(&callback, result); 257 }
188 } 258 }
189 259
190 void PPB_FileRef_Proxy::OnMsgTouch(const HostResource& host_resource, 260 void PPB_FileRef_Proxy::OnMsgTouch(const HostResource& host_resource,
191 PP_Time last_access, 261 PP_Time last_access,
192 PP_Time last_modified, 262 PP_Time last_modified,
193 uint32_t serialized_callback) { 263 int callback_id) {
194 EnterHostFromHostResource<PPB_FileRef_API> enter(host_resource); 264 EnterHostFromHostResourceForceCallback<PPB_FileRef_API> enter(
195 if (enter.failed()) 265 host_resource, callback_factory_,
196 return; 266 &PPB_FileRef_Proxy::OnCallbackCompleteInHost, host_resource, callback_id);
197 PP_CompletionCallback callback = ReceiveCallback(serialized_callback); 267 if (enter.succeeded()) {
198 int32_t result = enter.object()->Touch(last_access, last_modified, callback); 268 enter.SetResult(enter.object()->Touch(last_access, last_modified,
199 if (result != PP_OK_COMPLETIONPENDING) 269 enter.callback()));
200 PP_RunCompletionCallback(&callback, result); 270 }
201 } 271 }
202 272
203 void PPB_FileRef_Proxy::OnMsgDelete(const HostResource& host_resource, 273 void PPB_FileRef_Proxy::OnMsgDelete(const HostResource& host_resource,
204 uint32_t serialized_callback) { 274 int callback_id) {
205 EnterHostFromHostResource<PPB_FileRef_API> enter(host_resource); 275 EnterHostFromHostResourceForceCallback<PPB_FileRef_API> enter(
206 if (enter.failed()) 276 host_resource, callback_factory_,
207 return; 277 &PPB_FileRef_Proxy::OnCallbackCompleteInHost, host_resource, callback_id);
208 PP_CompletionCallback callback = ReceiveCallback(serialized_callback); 278 if (enter.succeeded())
209 int32_t result = enter.object()->Delete(callback); 279 enter.SetResult(enter.object()->Delete(enter.callback()));
210 if (result != PP_OK_COMPLETIONPENDING)
211 PP_RunCompletionCallback(&callback, result);
212 } 280 }
213 281
214 void PPB_FileRef_Proxy::OnMsgRename(const HostResource& file_ref, 282 void PPB_FileRef_Proxy::OnMsgRename(const HostResource& file_ref,
215 const HostResource& new_file_ref, 283 const HostResource& new_file_ref,
216 uint32_t serialized_callback) { 284 int callback_id) {
217 EnterHostFromHostResource<PPB_FileRef_API> enter(file_ref); 285 EnterHostFromHostResourceForceCallback<PPB_FileRef_API> enter(
218 if (enter.failed()) 286 file_ref, callback_factory_,
219 return; 287 &PPB_FileRef_Proxy::OnCallbackCompleteInHost, file_ref, callback_id);
220 PP_CompletionCallback callback = ReceiveCallback(serialized_callback); 288 if (enter.succeeded()) {
221 int32_t result = enter.object()->Rename(new_file_ref.host_resource(), 289 enter.SetResult(enter.object()->Rename(new_file_ref.host_resource(),
222 callback); 290 enter.callback()));
223 if (result != PP_OK_COMPLETIONPENDING) 291 }
224 PP_RunCompletionCallback(&callback, result); 292 }
293
294 void PPB_FileRef_Proxy::OnMsgCallbackComplete(
295 const HostResource& host_resource,
296 int callback_id,
297 int32_t result) {
298 // Forward the callback info to the plugin resource.
299 EnterPluginFromHostResource<PPB_FileRef_API> enter(host_resource);
300 if (enter.succeeded())
301 static_cast<FileRef*>(enter.object())->ExecuteCallback(callback_id, result);
302 }
303
304 void PPB_FileRef_Proxy::OnCallbackCompleteInHost(
305 int32_t result,
306 const HostResource& host_resource,
307 int callback_id) {
308 // Execute OnMsgCallbackComplete in the plugin process.
309 Send(new PpapiMsg_PPBFileRef_CallbackComplete(
310 INTERFACE_ID_PPB_FILE_REF, host_resource, callback_id, result));
225 } 311 }
226 312
227 } // namespace proxy 313 } // namespace proxy
228 } // namespace ppapi 314 } // namespace ppapi
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698