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

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

Issue 7745005: Initial work for UDP Pepper API (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: more changes from code reviews Created 9 years, 3 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_flash_udp_socket_proxy.h ('k') | ppapi/proxy/resource_creation_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
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "ppapi/proxy/ppb_flash_udp_socket_proxy.h"
6
7 #include <algorithm>
8 #include <cstring>
9 #include <map>
10
11 #include "base/logging.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/message_loop.h"
14 #include "base/task.h"
15 #include "ppapi/c/pp_errors.h"
16 #include "ppapi/proxy/plugin_dispatcher.h"
17 #include "ppapi/proxy/plugin_resource_tracker.h"
18 #include "ppapi/proxy/ppapi_messages.h"
19 #include "ppapi/shared_impl/resource.h"
20 #include "ppapi/thunk/ppb_flash_udp_socket_api.h"
21 #include "ppapi/thunk/thunk.h"
22
23 using ppapi::thunk::PPB_Flash_UDPSocket_API;
24
25 namespace ppapi {
26 namespace proxy {
27
28 const int32_t kFlashUDPSocketMaxReadSize = 1024 * 1024;
29 const int32_t kFlashUDPSocketMaxWriteSize = 1024 * 1024;
30
31 class FlashUDPSocket;
32
33 namespace {
34
35 typedef std::map<uint32, FlashUDPSocket*> IDToSocketMap;
36 IDToSocketMap* g_id_to_socket = NULL;
37
38 class AbortCallbackTask : public Task {
39 public:
40 explicit AbortCallbackTask(PP_CompletionCallback callback)
41 : callback_(callback) {}
42 virtual ~AbortCallbackTask() {}
43 virtual void Run() {
44 if (callback_.func)
45 PP_RunCompletionCallback(&callback_, PP_ERROR_ABORTED);
46 }
47
48 private:
49 PP_CompletionCallback callback_;
50 };
51
52 InterfaceProxy* CreateFlashUDPSocketProxy(Dispatcher* dispatcher) {
53 return new PPB_Flash_UDPSocket_Proxy(dispatcher);
54 }
55
56 } // namespace
57
58 class FlashUDPSocket : public PPB_Flash_UDPSocket_API,
59 public Resource {
60 public:
61 FlashUDPSocket(const HostResource& resource, uint32 socket_id);
62 virtual ~FlashUDPSocket();
63
64 // ResourceObjectBase overrides.
65 virtual PPB_Flash_UDPSocket_API* AsPPB_Flash_UDPSocket_API() OVERRIDE;
66
67 // PPB_Flash_UDPSocket_API implementation.
68 virtual int32_t Bind(const PP_Flash_NetAddress* addr,
69 PP_CompletionCallback callback) OVERRIDE;
70 virtual int32_t RecvFrom(char* buffer,
71 int32_t num_bytes,
72 PP_CompletionCallback callback) OVERRIDE;
73 virtual PP_Bool GetRecvFromAddress(PP_Flash_NetAddress* addr) OVERRIDE;
74
75 virtual int32_t SendTo(const char* buffer,
76 int32_t num_bytes,
77 const PP_Flash_NetAddress* addr,
78 PP_CompletionCallback callback) OVERRIDE;
79 virtual void Close() OVERRIDE;
80
81 // Notifications from the proxy.
82 void OnBindCompleted(bool succeeded);
83 void OnRecvFromCompleted(bool succeeded,
84 const std::string& data,
85 const PP_Flash_NetAddress& addr);
86 void OnSendToCompleted(bool succeeded,
87 int32_t bytes_written);
88
89 private:
90 void PostAbortAndClearIfNecessary(PP_CompletionCallback* callback);
91
92 PluginDispatcher* GetDispatcher() const {
93 return PluginDispatcher::GetForResource(this);
94 }
95
96 uint32 socket_id_;
97
98 bool bind_in_progress_;
99 bool sendto_pending_;
100
101 PP_CompletionCallback bind_callback_;
102 PP_CompletionCallback recvfrom_callback_;
103 PP_CompletionCallback sendto_callback_;
104
105 char* read_buffer_;
106 int32_t bytes_to_read_;
107
108 PP_Flash_NetAddress recvfrom_addr_;
109
110 DISALLOW_COPY_AND_ASSIGN(FlashUDPSocket);
111 };
112
113 FlashUDPSocket::FlashUDPSocket(const HostResource& resource,
114 uint32 socket_id)
115 : Resource(resource),
116 socket_id_(socket_id),
117 bind_in_progress_(false),
118 sendto_pending_(false),
119 bind_callback_(PP_BlockUntilComplete()),
120 recvfrom_callback_(PP_BlockUntilComplete()),
121 sendto_callback_(PP_BlockUntilComplete()),
122 read_buffer_(NULL),
123 bytes_to_read_(-1) {
124 DCHECK(socket_id != 0);
125
126 recvfrom_addr_.size = 0;
127 memset(recvfrom_addr_.data, 0, sizeof(recvfrom_addr_.data));
128
129 if (!g_id_to_socket)
130 g_id_to_socket = new IDToSocketMap();
131 DCHECK(g_id_to_socket->find(socket_id) == g_id_to_socket->end());
132 (*g_id_to_socket)[socket_id] = this;
133 }
134
135 FlashUDPSocket::~FlashUDPSocket() {
136 Close();
137 }
138
139 PPB_Flash_UDPSocket_API* FlashUDPSocket::AsPPB_Flash_UDPSocket_API() {
140 return this;
141 }
142
143 int32_t FlashUDPSocket::Bind(const PP_Flash_NetAddress* addr,
144 PP_CompletionCallback callback) {
145 if (!addr || !callback.func)
146 return PP_ERROR_BADARGUMENT;
147 if (bind_in_progress_)
yzshen1 2011/09/21 18:46:03 If you use this boolean value to indicate "it has
mtilburg 2011/09/22 13:53:23 Done.
148 return PP_ERROR_FAILED;
149
150 bind_callback_ = callback;
151
152 scoped_ptr<IPC::Message> msg_deletor(
153 new PpapiHostMsg_PPBFlashUDPSocket_Bind(socket_id_, *addr));
154
155 GetDispatcher()->SendToBrowser(msg_deletor.release());
156 bind_in_progress_ = true;
157
158 return PP_OK_COMPLETIONPENDING;
159 }
160
161 int32_t FlashUDPSocket::RecvFrom(char* buffer,
162 int32_t num_bytes,
163 PP_CompletionCallback callback) {
164 if (!buffer || num_bytes <= 0 || !callback.func)
165 return PP_ERROR_BADARGUMENT;
166
167 if (recvfrom_callback_.func)
168 return PP_ERROR_INPROGRESS;
169
170 read_buffer_ = buffer;
171 bytes_to_read_ = std::min(num_bytes, kFlashUDPSocketMaxReadSize);
172 recvfrom_callback_ = callback;
173
174 // Send the request, the browser will call us back via RecvFromACK.
175 GetDispatcher()->SendToBrowser(
176 new PpapiHostMsg_PPBFlashUDPSocket_RecvFrom(
177 socket_id_, num_bytes));
178 return PP_OK_COMPLETIONPENDING;
179 }
180
181 PP_Bool FlashUDPSocket::GetRecvFromAddress(PP_Flash_NetAddress* addr) {
182 if (!addr)
183 return PP_FALSE;
184
185 *addr = recvfrom_addr_;
186 return PP_TRUE;
187 }
188
189 int32_t FlashUDPSocket::SendTo(const char* buffer,
190 int32_t num_bytes,
191 const PP_Flash_NetAddress* addr,
192 PP_CompletionCallback callback) {
193 if (!buffer || num_bytes <= 0 || !addr || !callback.func)
194 return PP_ERROR_BADARGUMENT;
195
196 if (num_bytes > kFlashUDPSocketMaxWriteSize)
197 num_bytes = kFlashUDPSocketMaxWriteSize;
198
199 sendto_callback_ = callback;
200
201 // Send the request, the browser will call us back via SendToACK.
202 GetDispatcher()->SendToBrowser(
203 new PpapiHostMsg_PPBFlashUDPSocket_SendTo(
204 socket_id_, std::string(buffer, num_bytes), *addr));
205
206 // Only one SendTo call at a time
207 sendto_pending_ = true;
yzshen1 2011/09/21 18:46:03 1) You haven't actually checked the value of sendt
mtilburg 2011/09/22 13:53:23 Done.
208
209 return PP_OK_COMPLETIONPENDING;
210 }
211
212 void FlashUDPSocket::Close() {
213 if (!bind_in_progress_)
yzshen1 2011/09/21 18:46:03 As I said, you should remember whether it has been
mtilburg 2011/09/22 13:53:23 so |binded_| (previously bind_in_progress_| will k
214 return;
215
216 bind_in_progress_ = false;
217
218 // After removed from the mapping, this object won't receive any notfications
219 // from the proxy.
220 DCHECK(g_id_to_socket->find(socket_id_) != g_id_to_socket->end());
221 g_id_to_socket->erase(socket_id_);
222
223 GetDispatcher()->SendToBrowser(
224 new PpapiHostMsg_PPBFlashUDPSocket_Close(socket_id_));
225 socket_id_ = 0;
226
227 sendto_pending_ = false;
228
229 PostAbortAndClearIfNecessary(&bind_callback_);
230 PostAbortAndClearIfNecessary(&recvfrom_callback_);
231 PostAbortAndClearIfNecessary(&sendto_callback_);
232 }
233
234 void FlashUDPSocket::OnBindCompleted(bool succeeded) {
235 if (!bind_callback_.func) {
236 NOTREACHED();
237 return;
238 }
239
240 PP_RunAndClearCompletionCallback(&bind_callback_,
241 succeeded ? PP_OK : PP_ERROR_FAILED);
242 }
243
244 void FlashUDPSocket::OnRecvFromCompleted(bool succeeded,
245 const std::string& data,
246 const PP_Flash_NetAddress& addr) {
247 if (!recvfrom_callback_.func || !read_buffer_) {
248 NOTREACHED();
249 return;
250 }
251
252 if (succeeded) {
253 CHECK_LE(static_cast<int32_t>(data.size()), bytes_to_read_);
254 if (!data.empty())
255 memcpy(read_buffer_, data.c_str(), data.size());
256 }
257 read_buffer_ = NULL;
258 bytes_to_read_ = -1;
259 recvfrom_addr_ = addr;
260
261 PP_RunAndClearCompletionCallback(
262 &recvfrom_callback_,
263 succeeded ? static_cast<int32_t>(data.size()) :
264 static_cast<int32_t>(PP_ERROR_FAILED));
265 }
266
267 void FlashUDPSocket::OnSendToCompleted(bool succeeded,
268 int32_t bytes_written) {
269 if (!sendto_callback_.func) {
270 NOTREACHED();
271 return;
272 }
273
274 PP_RunAndClearCompletionCallback(
275 &sendto_callback_,
276 succeeded ? bytes_written : static_cast<int32_t>(PP_ERROR_FAILED));
277
278 sendto_pending_ = false;
279 }
280
281 void FlashUDPSocket::PostAbortAndClearIfNecessary(
282 PP_CompletionCallback* callback) {
283 DCHECK(callback);
284
285 if (callback->func) {
286 MessageLoop::current()->PostTask(FROM_HERE,
287 new AbortCallbackTask(*callback));
288 *callback = PP_BlockUntilComplete();
289 }
290 }
291
292 PPB_Flash_UDPSocket_Proxy::PPB_Flash_UDPSocket_Proxy(Dispatcher* dispatcher)
293 : InterfaceProxy(dispatcher) {
294 }
295
296 PPB_Flash_UDPSocket_Proxy::~PPB_Flash_UDPSocket_Proxy() {
297 }
298
299 // static
300 const InterfaceProxy::Info* PPB_Flash_UDPSocket_Proxy::GetInfo() {
301 static const Info info = {
302 ::ppapi::thunk::GetPPB_Flash_UDPSocket_Thunk(),
303 PPB_FLASH_UDPSOCKET_INTERFACE,
304 INTERFACE_ID_PPB_FLASH_UDPSOCKET,
305 false,
306 &CreateFlashUDPSocketProxy,
307 };
308 return &info;
309 }
310
311 // static
312 PP_Resource PPB_Flash_UDPSocket_Proxy::CreateProxyResource(
313 PP_Instance instance) {
314 PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance);
315 if (!dispatcher)
316 return 0;
317
318 uint32 socket_id = 0;
319 dispatcher->SendToBrowser(new PpapiHostMsg_PPBFlashUDPSocket_Create(
320 INTERFACE_ID_PPB_FLASH_UDPSOCKET, dispatcher->plugin_dispatcher_id(),
321 &socket_id));
322 if (socket_id == 0)
323 return 0;
324
325 return (new FlashUDPSocket(HostResource::MakeInstanceOnly(instance),
326 socket_id))->GetReference();
327 }
328
329 bool PPB_Flash_UDPSocket_Proxy::OnMessageReceived(const IPC::Message& msg) {
330 bool handled = true;
331 IPC_BEGIN_MESSAGE_MAP(PPB_Flash_UDPSocket_Proxy, msg)
332 IPC_MESSAGE_HANDLER(PpapiMsg_PPBFlashUDPSocket_BindACK,
333 OnMsgBindACK)
334 IPC_MESSAGE_HANDLER(PpapiMsg_PPBFlashUDPSocket_RecvFromACK,
335 OnMsgRecvFromACK)
336 IPC_MESSAGE_HANDLER(PpapiMsg_PPBFlashUDPSocket_SendToACK,
337 OnMsgSendToACK)
338 IPC_MESSAGE_UNHANDLED(handled = false)
339 IPC_END_MESSAGE_MAP()
340 return handled;
341 }
342
343 void PPB_Flash_UDPSocket_Proxy::OnMsgBindACK(
344 uint32 /* plugin_dispatcher_id */,
345 uint32 socket_id,
346 bool succeeded) {
347 if (!g_id_to_socket) {
348 NOTREACHED();
349 return;
350 }
351 IDToSocketMap::iterator iter = g_id_to_socket->find(socket_id);
352 if (iter == g_id_to_socket->end())
353 return;
354 iter->second->OnBindCompleted(succeeded);
355 }
356
357 void PPB_Flash_UDPSocket_Proxy::OnMsgRecvFromACK(
358 uint32 /* plugin_dispatcher_id */,
359 uint32 socket_id,
360 bool succeeded,
361 const std::string& data,
362 const PP_Flash_NetAddress& addr) {
363 if (!g_id_to_socket) {
364 NOTREACHED();
365 return;
366 }
367 IDToSocketMap::iterator iter = g_id_to_socket->find(socket_id);
368 if (iter == g_id_to_socket->end())
369 return;
370 iter->second->OnRecvFromCompleted(succeeded, data, addr);
371 }
372
373 void PPB_Flash_UDPSocket_Proxy::OnMsgSendToACK(
374 uint32 /* plugin_dispatcher_id */,
375 uint32 socket_id,
376 bool succeeded,
377 int32_t bytes_written) {
378 if (!g_id_to_socket) {
379 NOTREACHED();
380 return;
381 }
382 IDToSocketMap::iterator iter = g_id_to_socket->find(socket_id);
383 if (iter == g_id_to_socket->end())
384 return;
385 iter->second->OnSendToCompleted(succeeded, bytes_written);
386 }
387
388 } // namespace proxy
389 } // namespace ppapi
390
OLDNEW
« no previous file with comments | « ppapi/proxy/ppb_flash_udp_socket_proxy.h ('k') | ppapi/proxy/resource_creation_proxy.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698