Chromium Code Reviews| 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 |