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

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: Merge 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_;
viettrungluu 2011/10/17 17:11:03 Seems bad that things will fail when this wraps, w
brettw 2011/10/17 19:49:20 I added a loop to check for duplicates.
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_(1) {
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 return;
viettrungluu 2011/10/17 17:11:03 Is this really an expected case? Should it ever be
brettw 2011/10/17 19:49:20 I think this happens a bunch, I added a comment.
151
152 // Executing the callback may mutate the callback list.
153 PP_CompletionCallback callback = found->second;
154 pending_callbacks_.erase(found);
155 PP_RunCompletionCallback(&callback, result);
156 }
157
158 int FileRef::SendCallback(PP_CompletionCallback callback) {
159 if (!callback.func)
160 return 0;
161 pending_callbacks_[next_callback_id_] = callback;
162 return next_callback_id_++;
163 }
164
105 PPB_FileRef_Proxy::PPB_FileRef_Proxy(Dispatcher* dispatcher) 165 PPB_FileRef_Proxy::PPB_FileRef_Proxy(Dispatcher* dispatcher)
106 : InterfaceProxy(dispatcher) { 166 : InterfaceProxy(dispatcher),
167 callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
107 } 168 }
108 169
109 PPB_FileRef_Proxy::~PPB_FileRef_Proxy() { 170 PPB_FileRef_Proxy::~PPB_FileRef_Proxy() {
110 } 171 }
111 172
112 // static 173 // static
113 PP_Resource PPB_FileRef_Proxy::CreateProxyResource(PP_Resource file_system, 174 PP_Resource PPB_FileRef_Proxy::CreateProxyResource(PP_Resource file_system,
114 const char* path) { 175 const char* path) {
115 Resource* file_system_object = 176 Resource* file_system_object =
116 PluginResourceTracker::GetInstance()->GetResource(file_system); 177 PluginResourceTracker::GetInstance()->GetResource(file_system);
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
170 231
171 void PPB_FileRef_Proxy::OnMsgGetParent(const HostResource& host_resource, 232 void PPB_FileRef_Proxy::OnMsgGetParent(const HostResource& host_resource,
172 PPB_FileRef_CreateInfo* result) { 233 PPB_FileRef_CreateInfo* result) {
173 EnterHostFromHostResource<PPB_FileRef_API> enter(host_resource); 234 EnterHostFromHostResource<PPB_FileRef_API> enter(host_resource);
174 if (enter.succeeded()) 235 if (enter.succeeded())
175 SerializeFileRef(enter.object()->GetParent(), result); 236 SerializeFileRef(enter.object()->GetParent(), result);
176 } 237 }
177 238
178 void PPB_FileRef_Proxy::OnMsgMakeDirectory(const HostResource& host_resource, 239 void PPB_FileRef_Proxy::OnMsgMakeDirectory(const HostResource& host_resource,
179 PP_Bool make_ancestors, 240 PP_Bool make_ancestors,
180 uint32_t serialized_callback) { 241 int callback_id) {
181 EnterHostFromHostResource<PPB_FileRef_API> enter(host_resource); 242 EnterHostFromHostResourceForceCallback<PPB_FileRef_API> enter(
182 if (enter.failed()) 243 host_resource, callback_factory_,
183 return; 244 &PPB_FileRef_Proxy::OnCallbackCompleteInHost, host_resource, callback_id);
184 PP_CompletionCallback callback = ReceiveCallback(serialized_callback); 245 if (enter.succeeded()) {
185 int32_t result = enter.object()->MakeDirectory(make_ancestors, callback); 246 enter.SetResult(enter.object()->MakeDirectory(make_ancestors,
186 if (result != PP_OK_COMPLETIONPENDING) 247 enter.callback()));
187 PP_RunCompletionCallback(&callback, result); 248 }
188 } 249 }
189 250
190 void PPB_FileRef_Proxy::OnMsgTouch(const HostResource& host_resource, 251 void PPB_FileRef_Proxy::OnMsgTouch(const HostResource& host_resource,
191 PP_Time last_access, 252 PP_Time last_access,
192 PP_Time last_modified, 253 PP_Time last_modified,
193 uint32_t serialized_callback) { 254 int callback_id) {
194 EnterHostFromHostResource<PPB_FileRef_API> enter(host_resource); 255 EnterHostFromHostResourceForceCallback<PPB_FileRef_API> enter(
195 if (enter.failed()) 256 host_resource, callback_factory_,
196 return; 257 &PPB_FileRef_Proxy::OnCallbackCompleteInHost, host_resource, callback_id);
197 PP_CompletionCallback callback = ReceiveCallback(serialized_callback); 258 if (enter.succeeded()) {
198 int32_t result = enter.object()->Touch(last_access, last_modified, callback); 259 enter.SetResult(enter.object()->Touch(last_access, last_modified,
199 if (result != PP_OK_COMPLETIONPENDING) 260 enter.callback()));
200 PP_RunCompletionCallback(&callback, result); 261 }
201 } 262 }
202 263
203 void PPB_FileRef_Proxy::OnMsgDelete(const HostResource& host_resource, 264 void PPB_FileRef_Proxy::OnMsgDelete(const HostResource& host_resource,
204 uint32_t serialized_callback) { 265 int callback_id) {
205 EnterHostFromHostResource<PPB_FileRef_API> enter(host_resource); 266 EnterHostFromHostResourceForceCallback<PPB_FileRef_API> enter(
206 if (enter.failed()) 267 host_resource, callback_factory_,
207 return; 268 &PPB_FileRef_Proxy::OnCallbackCompleteInHost, host_resource, callback_id);
208 PP_CompletionCallback callback = ReceiveCallback(serialized_callback); 269 if (enter.succeeded())
209 int32_t result = enter.object()->Delete(callback); 270 enter.SetResult(enter.object()->Delete(enter.callback()));
210 if (result != PP_OK_COMPLETIONPENDING)
211 PP_RunCompletionCallback(&callback, result);
212 } 271 }
213 272
214 void PPB_FileRef_Proxy::OnMsgRename(const HostResource& file_ref, 273 void PPB_FileRef_Proxy::OnMsgRename(const HostResource& file_ref,
215 const HostResource& new_file_ref, 274 const HostResource& new_file_ref,
216 uint32_t serialized_callback) { 275 int callback_id) {
217 EnterHostFromHostResource<PPB_FileRef_API> enter(file_ref); 276 EnterHostFromHostResourceForceCallback<PPB_FileRef_API> enter(
218 if (enter.failed()) 277 file_ref, callback_factory_,
219 return; 278 &PPB_FileRef_Proxy::OnCallbackCompleteInHost, file_ref, callback_id);
220 PP_CompletionCallback callback = ReceiveCallback(serialized_callback); 279 if (enter.succeeded()) {
221 int32_t result = enter.object()->Rename(new_file_ref.host_resource(), 280 enter.SetResult(enter.object()->Rename(new_file_ref.host_resource(),
222 callback); 281 enter.callback()));
223 if (result != PP_OK_COMPLETIONPENDING) 282 }
224 PP_RunCompletionCallback(&callback, result); 283 }
284
285 void PPB_FileRef_Proxy::OnMsgCallbackComplete(
286 const HostResource& host_resource,
287 int callback_id,
288 int32_t result) {
289 // Forward the callback info to the plugin resource.
290 EnterPluginFromHostResource<PPB_FileRef_API> enter(host_resource);
291 if (enter.succeeded())
292 static_cast<FileRef*>(enter.object())->ExecuteCallback(callback_id, result);
293 }
294
295 void PPB_FileRef_Proxy::OnCallbackCompleteInHost(
296 int32_t result,
297 const HostResource& host_resource,
298 int callback_id) {
299 // Execute OnMsgCallbackComplete in the plugin process.
300 Send(new PpapiMsg_PPBFileRef_CallbackComplete(
301 INTERFACE_ID_PPB_FILE_REF, host_resource, callback_id, result));
225 } 302 }
226 303
227 } // namespace proxy 304 } // namespace proxy
228 } // namespace ppapi 305 } // namespace ppapi
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698