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

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

Issue 8364040: Revert 106677 (caused several PPAPI test timeouts, see http://crbug.com/101154) (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: 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
« no previous file with comments | « ppapi/proxy/ppb_file_ref_proxy.h ('k') | ppapi/proxy/ppb_instance_proxy.h » ('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 #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"
10 #include "ppapi/c/pp_errors.h" 7 #include "ppapi/c/pp_errors.h"
11 #include "ppapi/c/ppb_file_ref.h" 8 #include "ppapi/c/ppb_file_ref.h"
12 #include "ppapi/c/private/ppb_proxy_private.h" 9 #include "ppapi/c/private/ppb_proxy_private.h"
13 #include "ppapi/proxy/enter_proxy.h" 10 #include "ppapi/proxy/enter_proxy.h"
14 #include "ppapi/proxy/host_dispatcher.h" 11 #include "ppapi/proxy/host_dispatcher.h"
15 #include "ppapi/proxy/plugin_dispatcher.h" 12 #include "ppapi/proxy/plugin_dispatcher.h"
16 #include "ppapi/proxy/ppapi_messages.h" 13 #include "ppapi/proxy/ppapi_messages.h"
17 #include "ppapi/proxy/serialized_var.h" 14 #include "ppapi/proxy/serialized_var.h"
18 #include "ppapi/shared_impl/file_ref_impl.h" 15 #include "ppapi/shared_impl/file_ref_impl.h"
19 #include "ppapi/thunk/resource_creation_api.h" 16 #include "ppapi/thunk/resource_creation_api.h"
(...skipping 16 matching lines...) Expand all
36 virtual PP_Resource GetParent() OVERRIDE; 33 virtual PP_Resource GetParent() OVERRIDE;
37 virtual int32_t MakeDirectory(PP_Bool make_ancestors, 34 virtual int32_t MakeDirectory(PP_Bool make_ancestors,
38 PP_CompletionCallback callback) OVERRIDE; 35 PP_CompletionCallback callback) OVERRIDE;
39 virtual int32_t Touch(PP_Time last_access_time, 36 virtual int32_t Touch(PP_Time last_access_time,
40 PP_Time last_modified_time, 37 PP_Time last_modified_time,
41 PP_CompletionCallback callback) OVERRIDE; 38 PP_CompletionCallback callback) OVERRIDE;
42 virtual int32_t Delete(PP_CompletionCallback callback) OVERRIDE; 39 virtual int32_t Delete(PP_CompletionCallback callback) OVERRIDE;
43 virtual int32_t Rename(PP_Resource new_file_ref, 40 virtual int32_t Rename(PP_Resource new_file_ref,
44 PP_CompletionCallback callback) OVERRIDE; 41 PP_CompletionCallback callback) OVERRIDE;
45 42
46 // Executes the pending callback with the given ID. See pending_callbacks_.
47 void ExecuteCallback(int callback_id, int32_t result);
48
49 private: 43 private:
50 PluginDispatcher* GetDispatcher() const { 44 PluginDispatcher* GetDispatcher() const {
51 return PluginDispatcher::GetForResource(this); 45 return PluginDispatcher::GetForResource(this);
52 } 46 }
53 47
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
69 DISALLOW_IMPLICIT_CONSTRUCTORS(FileRef); 48 DISALLOW_IMPLICIT_CONSTRUCTORS(FileRef);
70 }; 49 };
71 50
72 FileRef::FileRef(const PPB_FileRef_CreateInfo& info) 51 FileRef::FileRef(const PPB_FileRef_CreateInfo& info)
73 : FileRefImpl(FileRefImpl::InitAsProxy(), info), 52 : FileRefImpl(FileRefImpl::InitAsProxy(), info) {
74 next_callback_id_(0) {
75 } 53 }
76 54
77 FileRef::~FileRef() { 55 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 }
86 } 56 }
87 57
88 PP_Resource FileRef::GetParent() { 58 PP_Resource FileRef::GetParent() {
89 PPB_FileRef_CreateInfo create_info; 59 PPB_FileRef_CreateInfo create_info;
90 GetDispatcher()->Send(new PpapiHostMsg_PPBFileRef_GetParent( 60 GetDispatcher()->Send(new PpapiHostMsg_PPBFileRef_GetParent(
91 API_ID_PPB_FILE_REF, host_resource(), &create_info)); 61 API_ID_PPB_FILE_REF, host_resource(), &create_info));
92 return PPB_FileRef_Proxy::DeserializeFileRef(create_info); 62 return PPB_FileRef_Proxy::DeserializeFileRef(create_info);
93 } 63 }
94 64
95 int32_t FileRef::MakeDirectory(PP_Bool make_ancestors, 65 int32_t FileRef::MakeDirectory(PP_Bool make_ancestors,
96 PP_CompletionCallback callback) { 66 PP_CompletionCallback callback) {
97 int callback_id = SendCallback(callback);
98 if (!callback_id)
99 return PP_ERROR_BADARGUMENT;
100
101 GetDispatcher()->Send(new PpapiHostMsg_PPBFileRef_MakeDirectory( 67 GetDispatcher()->Send(new PpapiHostMsg_PPBFileRef_MakeDirectory(
102 API_ID_PPB_FILE_REF, host_resource(), make_ancestors, callback_id)); 68 API_ID_PPB_FILE_REF, host_resource(), make_ancestors,
69 GetDispatcher()->callback_tracker().SendCallback(callback)));
103 return PP_OK_COMPLETIONPENDING; 70 return PP_OK_COMPLETIONPENDING;
104 } 71 }
105 72
106 int32_t FileRef::Touch(PP_Time last_access_time, 73 int32_t FileRef::Touch(PP_Time last_access_time,
107 PP_Time last_modified_time, 74 PP_Time last_modified_time,
108 PP_CompletionCallback callback) { 75 PP_CompletionCallback callback) {
109 int callback_id = SendCallback(callback);
110 if (!callback_id)
111 return PP_ERROR_BADARGUMENT;
112
113 GetDispatcher()->Send(new PpapiHostMsg_PPBFileRef_Touch( 76 GetDispatcher()->Send(new PpapiHostMsg_PPBFileRef_Touch(
114 API_ID_PPB_FILE_REF, host_resource(), 77 API_ID_PPB_FILE_REF, host_resource(),
115 last_access_time, last_modified_time, callback_id)); 78 last_access_time, last_modified_time,
79 GetDispatcher()->callback_tracker().SendCallback(callback)));
116 return PP_OK_COMPLETIONPENDING; 80 return PP_OK_COMPLETIONPENDING;
117 } 81 }
118 82
119 int32_t FileRef::Delete(PP_CompletionCallback callback) { 83 int32_t FileRef::Delete(PP_CompletionCallback callback) {
120 int callback_id = SendCallback(callback);
121 if (!callback_id)
122 return PP_ERROR_BADARGUMENT;
123
124 GetDispatcher()->Send(new PpapiHostMsg_PPBFileRef_Delete( 84 GetDispatcher()->Send(new PpapiHostMsg_PPBFileRef_Delete(
125 API_ID_PPB_FILE_REF, host_resource(), callback_id)); 85 API_ID_PPB_FILE_REF, host_resource(),
86 GetDispatcher()->callback_tracker().SendCallback(callback)));
126 return PP_OK_COMPLETIONPENDING; 87 return PP_OK_COMPLETIONPENDING;
127 } 88 }
128 89
129 int32_t FileRef::Rename(PP_Resource new_file_ref, 90 int32_t FileRef::Rename(PP_Resource new_file_ref,
130 PP_CompletionCallback callback) { 91 PP_CompletionCallback callback) {
131 int callback_id = SendCallback(callback);
132 if (!callback_id)
133 return PP_ERROR_BADARGUMENT;
134
135 Resource* new_file_ref_object = 92 Resource* new_file_ref_object =
136 PpapiGlobals::Get()->GetResourceTracker()->GetResource(new_file_ref); 93 PpapiGlobals::Get()->GetResourceTracker()->GetResource(new_file_ref);
137 if (!new_file_ref_object || 94 if (!new_file_ref_object ||
138 new_file_ref_object->host_resource().instance() != pp_instance()) 95 new_file_ref_object->host_resource().instance() != pp_instance())
139 return PP_ERROR_BADRESOURCE; 96 return PP_ERROR_BADRESOURCE;
140 97
141 GetDispatcher()->Send(new PpapiHostMsg_PPBFileRef_Rename( 98 GetDispatcher()->Send(new PpapiHostMsg_PPBFileRef_Rename(
142 API_ID_PPB_FILE_REF, host_resource(), 99 API_ID_PPB_FILE_REF, host_resource(),
143 new_file_ref_object->host_resource(), callback_id)); 100 new_file_ref_object->host_resource(),
101 GetDispatcher()->callback_tracker().SendCallback(callback)));
144 return PP_OK_COMPLETIONPENDING; 102 return PP_OK_COMPLETIONPENDING;
145 } 103 }
146 104
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
174 PPB_FileRef_Proxy::PPB_FileRef_Proxy(Dispatcher* dispatcher) 105 PPB_FileRef_Proxy::PPB_FileRef_Proxy(Dispatcher* dispatcher)
175 : InterfaceProxy(dispatcher), 106 : InterfaceProxy(dispatcher) {
176 callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
177 } 107 }
178 108
179 PPB_FileRef_Proxy::~PPB_FileRef_Proxy() { 109 PPB_FileRef_Proxy::~PPB_FileRef_Proxy() {
180 } 110 }
181 111
182 // static 112 // static
183 PP_Resource PPB_FileRef_Proxy::CreateProxyResource(PP_Resource file_system, 113 PP_Resource PPB_FileRef_Proxy::CreateProxyResource(PP_Resource file_system,
184 const char* path) { 114 const char* path) {
185 Resource* file_system_object = 115 Resource* file_system_object =
186 PpapiGlobals::Get()->GetResourceTracker()->GetResource(file_system); 116 PpapiGlobals::Get()->GetResourceTracker()->GetResource(file_system);
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
240 170
241 void PPB_FileRef_Proxy::OnMsgGetParent(const HostResource& host_resource, 171 void PPB_FileRef_Proxy::OnMsgGetParent(const HostResource& host_resource,
242 PPB_FileRef_CreateInfo* result) { 172 PPB_FileRef_CreateInfo* result) {
243 EnterHostFromHostResource<PPB_FileRef_API> enter(host_resource); 173 EnterHostFromHostResource<PPB_FileRef_API> enter(host_resource);
244 if (enter.succeeded()) 174 if (enter.succeeded())
245 SerializeFileRef(enter.object()->GetParent(), result); 175 SerializeFileRef(enter.object()->GetParent(), result);
246 } 176 }
247 177
248 void PPB_FileRef_Proxy::OnMsgMakeDirectory(const HostResource& host_resource, 178 void PPB_FileRef_Proxy::OnMsgMakeDirectory(const HostResource& host_resource,
249 PP_Bool make_ancestors, 179 PP_Bool make_ancestors,
250 int callback_id) { 180 uint32_t serialized_callback) {
251 EnterHostFromHostResourceForceCallback<PPB_FileRef_API> enter( 181 EnterHostFromHostResource<PPB_FileRef_API> enter(host_resource);
252 host_resource, callback_factory_, 182 if (enter.failed())
253 &PPB_FileRef_Proxy::OnCallbackCompleteInHost, host_resource, callback_id); 183 return;
254 if (enter.succeeded()) { 184 PP_CompletionCallback callback = ReceiveCallback(serialized_callback);
255 enter.SetResult(enter.object()->MakeDirectory(make_ancestors, 185 int32_t result = enter.object()->MakeDirectory(make_ancestors, callback);
256 enter.callback())); 186 if (result != PP_OK_COMPLETIONPENDING)
257 } 187 PP_RunCompletionCallback(&callback, result);
258 } 188 }
259 189
260 void PPB_FileRef_Proxy::OnMsgTouch(const HostResource& host_resource, 190 void PPB_FileRef_Proxy::OnMsgTouch(const HostResource& host_resource,
261 PP_Time last_access, 191 PP_Time last_access,
262 PP_Time last_modified, 192 PP_Time last_modified,
263 int callback_id) { 193 uint32_t serialized_callback) {
264 EnterHostFromHostResourceForceCallback<PPB_FileRef_API> enter( 194 EnterHostFromHostResource<PPB_FileRef_API> enter(host_resource);
265 host_resource, callback_factory_, 195 if (enter.failed())
266 &PPB_FileRef_Proxy::OnCallbackCompleteInHost, host_resource, callback_id); 196 return;
267 if (enter.succeeded()) { 197 PP_CompletionCallback callback = ReceiveCallback(serialized_callback);
268 enter.SetResult(enter.object()->Touch(last_access, last_modified, 198 int32_t result = enter.object()->Touch(last_access, last_modified, callback);
269 enter.callback())); 199 if (result != PP_OK_COMPLETIONPENDING)
270 } 200 PP_RunCompletionCallback(&callback, result);
271 } 201 }
272 202
273 void PPB_FileRef_Proxy::OnMsgDelete(const HostResource& host_resource, 203 void PPB_FileRef_Proxy::OnMsgDelete(const HostResource& host_resource,
274 int callback_id) { 204 uint32_t serialized_callback) {
275 EnterHostFromHostResourceForceCallback<PPB_FileRef_API> enter( 205 EnterHostFromHostResource<PPB_FileRef_API> enter(host_resource);
276 host_resource, callback_factory_, 206 if (enter.failed())
277 &PPB_FileRef_Proxy::OnCallbackCompleteInHost, host_resource, callback_id); 207 return;
278 if (enter.succeeded()) 208 PP_CompletionCallback callback = ReceiveCallback(serialized_callback);
279 enter.SetResult(enter.object()->Delete(enter.callback())); 209 int32_t result = enter.object()->Delete(callback);
210 if (result != PP_OK_COMPLETIONPENDING)
211 PP_RunCompletionCallback(&callback, result);
280 } 212 }
281 213
282 void PPB_FileRef_Proxy::OnMsgRename(const HostResource& file_ref, 214 void PPB_FileRef_Proxy::OnMsgRename(const HostResource& file_ref,
283 const HostResource& new_file_ref, 215 const HostResource& new_file_ref,
284 int callback_id) { 216 uint32_t serialized_callback) {
285 EnterHostFromHostResourceForceCallback<PPB_FileRef_API> enter( 217 EnterHostFromHostResource<PPB_FileRef_API> enter(file_ref);
286 file_ref, callback_factory_, 218 if (enter.failed())
287 &PPB_FileRef_Proxy::OnCallbackCompleteInHost, file_ref, callback_id); 219 return;
288 if (enter.succeeded()) { 220 PP_CompletionCallback callback = ReceiveCallback(serialized_callback);
289 enter.SetResult(enter.object()->Rename(new_file_ref.host_resource(), 221 int32_t result = enter.object()->Rename(new_file_ref.host_resource(),
290 enter.callback())); 222 callback);
291 } 223 if (result != PP_OK_COMPLETIONPENDING)
292 } 224 PP_RunCompletionCallback(&callback, result);
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 API_ID_PPB_FILE_REF, host_resource, callback_id, result));
311 } 225 }
312 226
313 } // namespace proxy 227 } // namespace proxy
314 } // namespace ppapi 228 } // namespace ppapi
OLDNEW
« no previous file with comments | « ppapi/proxy/ppb_file_ref_proxy.h ('k') | ppapi/proxy/ppb_instance_proxy.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698