OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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/host_dispatcher.h" | 5 #include "ppapi/proxy/host_dispatcher.h" |
6 | 6 |
7 #include <map> | 7 #include <map> |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "ppapi/c/private/ppb_proxy_private.h" | 10 #include "ppapi/c/private/ppb_proxy_private.h" |
(...skipping 23 matching lines...) Expand all Loading... |
34 NOTREACHED(); | 34 NOTREACHED(); |
35 return PP_TRUE; | 35 return PP_TRUE; |
36 } | 36 } |
37 | 37 |
38 bool usable = true; | 38 bool usable = true; |
39 if (!found->second->Send(new PpapiMsg_ReserveInstanceId(instance, &usable))) | 39 if (!found->second->Send(new PpapiMsg_ReserveInstanceId(instance, &usable))) |
40 return PP_TRUE; | 40 return PP_TRUE; |
41 return BoolToPPBool(usable); | 41 return BoolToPPBool(usable); |
42 } | 42 } |
43 | 43 |
| 44 // Saves the state of the given bool and puts it back when it goes out of |
| 45 // scope. |
| 46 class BoolRestorer { |
| 47 public: |
| 48 BoolRestorer(bool* var) : var_(var), old_value_(*var) { |
| 49 } |
| 50 ~BoolRestorer() { |
| 51 *var_ = old_value_; |
| 52 } |
| 53 private: |
| 54 bool* var_; |
| 55 bool old_value_; |
| 56 }; |
| 57 |
44 } // namespace | 58 } // namespace |
45 | 59 |
46 HostDispatcher::HostDispatcher(base::ProcessHandle remote_process_handle, | 60 HostDispatcher::HostDispatcher(base::ProcessHandle remote_process_handle, |
47 PP_Module module, | 61 PP_Module module, |
48 GetInterfaceFunc local_get_interface) | 62 GetInterfaceFunc local_get_interface) |
49 : Dispatcher(remote_process_handle, local_get_interface), | 63 : Dispatcher(remote_process_handle, local_get_interface), |
50 pp_module_(module), | 64 pp_module_(module), |
51 ppb_proxy_(NULL) { | 65 ppb_proxy_(NULL) { |
52 if (!g_module_to_dispatcher) | 66 if (!g_module_to_dispatcher) |
53 g_module_to_dispatcher = new ModuleToDispatcherMap; | 67 g_module_to_dispatcher = new ModuleToDispatcherMap; |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
98 InstanceToDispatcherMap::iterator found = g_instance_to_dispatcher->find( | 112 InstanceToDispatcherMap::iterator found = g_instance_to_dispatcher->find( |
99 instance); | 113 instance); |
100 if (found != g_instance_to_dispatcher->end()) | 114 if (found != g_instance_to_dispatcher->end()) |
101 g_instance_to_dispatcher->erase(found); | 115 g_instance_to_dispatcher->erase(found); |
102 } | 116 } |
103 | 117 |
104 bool HostDispatcher::IsPlugin() const { | 118 bool HostDispatcher::IsPlugin() const { |
105 return false; | 119 return false; |
106 } | 120 } |
107 | 121 |
| 122 bool HostDispatcher::Send(IPC::Message* msg) { |
| 123 // Normal sync messages are set to unblock, which would normally cause the |
| 124 // plugin to be reentered to process them. We only want to do this when we |
| 125 // know the plugin is in a state to accept reentrancy. Since the plugin side |
| 126 // never clears this flag on messages it sends, we can't get deadlock, but we |
| 127 // may still get reentrancy in the host as a result. |
| 128 if (!allow_plugin_reentrancy_) |
| 129 msg->set_unblock(false); |
| 130 return Dispatcher::Send(msg); |
| 131 } |
| 132 |
108 bool HostDispatcher::OnMessageReceived(const IPC::Message& msg) { | 133 bool HostDispatcher::OnMessageReceived(const IPC::Message& msg) { |
| 134 // We only want to allow reentrancy when the most recent message from the |
| 135 // plugin was a scripting message. We save the old state of the flag on the |
| 136 // stack in case we're (we are the host) being reentered ourselves. The flag |
| 137 // is set to false here for all messages, and then the scripting API will |
| 138 // explicitly set it to true during processing of those messages that can be |
| 139 // reentered. |
| 140 BoolRestorer restorer(&allow_plugin_reentrancy_); |
| 141 allow_plugin_reentrancy_ = false; |
| 142 |
109 // Handle common control messages. | 143 // Handle common control messages. |
110 if (Dispatcher::OnMessageReceived(msg)) | 144 if (Dispatcher::OnMessageReceived(msg)) |
111 return true; | 145 return true; |
112 | 146 |
113 if (msg.routing_id() <= 0 && msg.routing_id() >= INTERFACE_ID_COUNT) { | 147 if (msg.routing_id() <= 0 && msg.routing_id() >= INTERFACE_ID_COUNT) { |
114 NOTREACHED(); | 148 NOTREACHED(); |
115 // TODO(brettw): kill the plugin if it starts sending invalid messages? | 149 // TODO(brettw): kill the plugin if it starts sending invalid messages? |
116 return true; | 150 return true; |
117 } | 151 } |
118 | 152 |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
195 } | 229 } |
196 | 230 |
197 InterfaceProxy* proxy = info->create_proxy(this, local_interface); | 231 InterfaceProxy* proxy = info->create_proxy(this, local_interface); |
198 target_proxies_[info->id].reset(proxy); | 232 target_proxies_[info->id].reset(proxy); |
199 return proxy; | 233 return proxy; |
200 } | 234 } |
201 | 235 |
202 } // namespace proxy | 236 } // namespace proxy |
203 } // namespace pp | 237 } // namespace pp |
204 | 238 |
OLD | NEW |