OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2014 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/message_handler.h" | |
6 | |
7 #include "ipc/ipc_message.h" | |
8 #include "ppapi/proxy/plugin_dispatcher.h" | |
9 #include "ppapi/proxy/ppapi_messages.h" | |
10 #include "ppapi/proxy/ppb_message_loop_proxy.h" | |
11 #include "ppapi/shared_impl/proxy_lock.h" | |
12 #include "ppapi/shared_impl/scoped_pp_var.h" | |
13 #include "ppapi/thunk/enter.h" | |
14 | |
15 namespace ppapi { | |
16 namespace proxy { | |
17 namespace { | |
18 | |
19 typedef PP_Var (*HandleBlockingMessageFunc)(PP_Instance, void*, PP_Var); | |
20 | |
21 void HandleBlockingMessageWrapper(HandleBlockingMessageFunc function, | |
22 PP_Instance instance, | |
23 void* user_data, | |
24 ScopedPPVar message_data, | |
25 scoped_ptr<IPC::Message> reply_msg) { | |
26 PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance); | |
27 if (!dispatcher) | |
28 return; | |
29 PP_Var return_value = CallWhileUnlocked(function, | |
30 instance, | |
31 user_data, | |
32 message_data.get()); | |
33 PpapiMsg_PPPMessageHandler_HandleBlockingMessage::WriteReplyParams( | |
34 reply_msg.get(), | |
35 SerializedVarReturnValue::Convert(dispatcher, return_value), | |
36 true /* was_handled */); | |
37 dispatcher->Send(reply_msg.release()); | |
38 } | |
39 | |
40 } // namespace | |
41 | |
42 //static | |
raymes
2014/06/06 06:38:17
nit: // static
| |
43 scoped_ptr<MessageHandler> MessageHandler::Create( | |
44 PP_Instance instance, | |
45 const PPP_MessageHandler_0_1* handler_if, | |
46 void* user_data, | |
47 PP_Resource message_loop, | |
48 int32_t* error) { | |
49 scoped_ptr<MessageHandler> result; | |
50 // The interface and all function pointers must be valid. | |
51 if (!handler_if || | |
52 !handler_if->HandleMessage || | |
53 !handler_if->HandleBlockingMessage || | |
54 !handler_if->Destroy) { | |
55 *error = PP_ERROR_BADARGUMENT; | |
56 return result.Pass(); | |
57 } | |
58 thunk::EnterResourceNoLock<thunk::PPB_MessageLoop_API> | |
59 enter_loop(message_loop, true); | |
60 if (enter_loop.failed()) { | |
61 *error = PP_ERROR_BADRESOURCE; | |
62 return result.Pass(); | |
63 } | |
64 scoped_refptr<MessageLoopResource> message_loop_resource( | |
65 static_cast<MessageLoopResource*>(enter_loop.object())); | |
66 if (message_loop_resource->is_main_thread_loop()) { | |
67 *error = PP_ERROR_WRONG_THREAD; | |
68 return result.Pass(); | |
69 } | |
70 | |
71 result.reset(new MessageHandler( | |
72 instance, handler_if, user_data, message_loop_resource)); | |
73 *error = PP_OK; | |
74 return result.Pass(); | |
75 } | |
76 | |
77 MessageHandler::~MessageHandler() { | |
78 // It's possible the message_loop_proxy is NULL if that loop has been quit. | |
79 // In that case, we unfortunately just can't call Destroy, so it might mean | |
80 // a leak. TODO(dmichael): Should we care about this? | |
raymes
2014/06/10 04:50:47
Should we update the docs here to document this? O
raymes
2014/06/16 05:33:32
I guess you decided this was useful to keep but I'
dmichael (off chromium)
2014/06/17 18:28:29
I took off the TODO in the latest patchset. I thou
raymes
2014/06/18 07:26:18
What I was really trying to ask is if the Destroy
dmichael (off chromium)
2014/06/18 16:15:32
Ah, good question. My point in having it was that
| |
81 if (message_loop_->message_loop_proxy()) { | |
82 // The posted task won't have the proxy lock, but that's OK, it doesn't | |
83 // touch any internal state; it's a direct call on the plugin's function. | |
84 message_loop_->message_loop_proxy()->PostTask(FROM_HERE, | |
85 base::Bind(handler_if_->Destroy, | |
86 instance_, | |
87 user_data_)); | |
88 } | |
89 } | |
90 | |
91 void MessageHandler::HandleMessage(ScopedPPVar var) { | |
92 // See note above about the proxy lock. | |
93 message_loop_->message_loop_proxy()->PostTask(FROM_HERE, | |
94 base::Bind(handler_if_->HandleMessage, | |
95 instance_, | |
96 user_data_, | |
97 var.Release())); | |
98 } | |
99 | |
100 void MessageHandler::HandleBlockingMessage(ScopedPPVar var, | |
101 scoped_ptr<IPC::Message> reply_msg) { | |
102 message_loop_->message_loop_proxy()->PostTask(FROM_HERE, | |
103 RunWhileLocked(base::Bind(&HandleBlockingMessageWrapper, | |
104 handler_if_->HandleBlockingMessage, | |
105 instance_, | |
106 user_data_, | |
107 var, | |
108 base::Passed(reply_msg.Pass())))); | |
109 } | |
110 | |
111 MessageHandler::MessageHandler( | |
raymes
2014/06/06 06:38:17
nit: I think we usually have the constructor befor
dmichael (off chromium)
2014/06/13 22:01:26
I was matching the order from the header. This is
| |
112 PP_Instance instance, | |
113 const PPP_MessageHandler_0_1* handler_if, | |
114 void* user_data, | |
115 scoped_refptr<MessageLoopResource> message_loop) | |
116 : instance_(instance), | |
117 handler_if_(handler_if), | |
118 user_data_(user_data), | |
119 message_loop_(message_loop) { | |
120 } | |
121 | |
122 } // namespace proxy | |
123 } // namespace ppapi | |
OLD | NEW |