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

Side by Side Diff: content/plugin/plugin_channel.cc

Issue 10069054: RefCounted types should not have public destructors, content/ remaining bits (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebased to Trunk Created 8 years, 7 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 | « content/plugin/plugin_channel.h ('k') | content/plugin/plugin_thread.cc » ('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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "content/plugin/plugin_channel.h" 5 #include "content/plugin/plugin_channel.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/command_line.h" 8 #include "base/command_line.h"
9 #include "base/process_util.h" 9 #include "base/process_util.h"
10 #include "base/string_util.h" 10 #include "base/string_util.h"
(...skipping 23 matching lines...) Expand all
34 const int kPluginReleaseTimeMinutes = 5; 34 const int kPluginReleaseTimeMinutes = 5;
35 35
36 } // namespace 36 } // namespace
37 37
38 // If a sync call to the renderer results in a modal dialog, we need to have a 38 // If a sync call to the renderer results in a modal dialog, we need to have a
39 // way to know so that we can run a nested message loop to simulate what would 39 // way to know so that we can run a nested message loop to simulate what would
40 // happen in a single process browser and avoid deadlock. 40 // happen in a single process browser and avoid deadlock.
41 class PluginChannel::MessageFilter : public IPC::ChannelProxy::MessageFilter { 41 class PluginChannel::MessageFilter : public IPC::ChannelProxy::MessageFilter {
42 public: 42 public:
43 MessageFilter() : channel_(NULL) { } 43 MessageFilter() : channel_(NULL) { }
44 ~MessageFilter() {
45 // Clean up in case of renderer crash.
46 for (ModalDialogEventMap::iterator i = modal_dialog_event_map_.begin();
47 i != modal_dialog_event_map_.end(); ++i) {
48 delete i->second.event;
49 }
50 }
51 44
52 base::WaitableEvent* GetModalDialogEvent( 45 base::WaitableEvent* GetModalDialogEvent(
53 gfx::NativeViewId containing_window) { 46 gfx::NativeViewId containing_window) {
54 base::AutoLock auto_lock(modal_dialog_event_map_lock_); 47 base::AutoLock auto_lock(modal_dialog_event_map_lock_);
55 if (!modal_dialog_event_map_.count(containing_window)) { 48 if (!modal_dialog_event_map_.count(containing_window)) {
56 NOTREACHED(); 49 NOTREACHED();
57 return NULL; 50 return NULL;
58 } 51 }
59 52
60 return modal_dialog_event_map_[containing_window].event; 53 return modal_dialog_event_map_[containing_window].event;
(...skipping 15 matching lines...) Expand all
76 MessageLoop::current()->DeleteSoon( 69 MessageLoop::current()->DeleteSoon(
77 FROM_HERE, modal_dialog_event_map_[containing_window].event); 70 FROM_HERE, modal_dialog_event_map_[containing_window].event);
78 modal_dialog_event_map_.erase(containing_window); 71 modal_dialog_event_map_.erase(containing_window);
79 } 72 }
80 73
81 bool Send(IPC::Message* message) { 74 bool Send(IPC::Message* message) {
82 // Need this function for the IPC_MESSAGE_HANDLER_DELAY_REPLY macro. 75 // Need this function for the IPC_MESSAGE_HANDLER_DELAY_REPLY macro.
83 return channel_->Send(message); 76 return channel_->Send(message);
84 } 77 }
85 78
86 private: 79 // IPC::ChannelProxy::MessageFilter:
87 void OnFilterAdded(IPC::Channel* channel) { channel_ = channel; } 80 void OnFilterAdded(IPC::Channel* channel) { channel_ = channel; }
88 81
89 bool OnMessageReceived(const IPC::Message& message) { 82 bool OnMessageReceived(const IPC::Message& message) {
90 IPC_BEGIN_MESSAGE_MAP(PluginChannel::MessageFilter, message) 83 IPC_BEGIN_MESSAGE_MAP(PluginChannel::MessageFilter, message)
91 IPC_MESSAGE_HANDLER_DELAY_REPLY(PluginMsg_Init, OnInit) 84 IPC_MESSAGE_HANDLER_DELAY_REPLY(PluginMsg_Init, OnInit)
92 IPC_MESSAGE_HANDLER(PluginMsg_SignalModalDialogEvent, 85 IPC_MESSAGE_HANDLER(PluginMsg_SignalModalDialogEvent,
93 OnSignalModalDialogEvent) 86 OnSignalModalDialogEvent)
94 IPC_MESSAGE_HANDLER(PluginMsg_ResetModalDialogEvent, 87 IPC_MESSAGE_HANDLER(PluginMsg_ResetModalDialogEvent,
95 OnResetModalDialogEvent) 88 OnResetModalDialogEvent)
96 IPC_END_MESSAGE_MAP() 89 IPC_END_MESSAGE_MAP()
97 return message.type() == PluginMsg_SignalModalDialogEvent::ID || 90 return message.type() == PluginMsg_SignalModalDialogEvent::ID ||
98 message.type() == PluginMsg_ResetModalDialogEvent::ID; 91 message.type() == PluginMsg_ResetModalDialogEvent::ID;
99 } 92 }
100 93
94
95
96 protected:
97 virtual ~MessageFilter() {
98 // Clean up in case of renderer crash.
99 for (ModalDialogEventMap::iterator i = modal_dialog_event_map_.begin();
100 i != modal_dialog_event_map_.end(); ++i) {
101 delete i->second.event;
102 }
103 }
104
105 private:
101 void OnInit(const PluginMsg_Init_Params& params, IPC::Message* reply_msg) { 106 void OnInit(const PluginMsg_Init_Params& params, IPC::Message* reply_msg) {
102 base::AutoLock auto_lock(modal_dialog_event_map_lock_); 107 base::AutoLock auto_lock(modal_dialog_event_map_lock_);
103 if (modal_dialog_event_map_.count(params.containing_window)) { 108 if (modal_dialog_event_map_.count(params.containing_window)) {
104 modal_dialog_event_map_[params.containing_window].refcount++; 109 modal_dialog_event_map_[params.containing_window].refcount++;
105 return; 110 return;
106 } 111 }
107 112
108 WaitableEventWrapper wrapper; 113 WaitableEventWrapper wrapper;
109 wrapper.event = new base::WaitableEvent(true, false); 114 wrapper.event = new base::WaitableEvent(true, false);
110 wrapper.refcount = 1; 115 wrapper.refcount = 1;
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
153 channel->renderer_id_ = renderer_id; 158 channel->renderer_id_ = renderer_id;
154 159
155 return channel; 160 return channel;
156 } 161 }
157 162
158 // static 163 // static
159 void PluginChannel::NotifyRenderersOfPendingShutdown() { 164 void PluginChannel::NotifyRenderersOfPendingShutdown() {
160 Broadcast(new PluginHostMsg_PluginShuttingDown()); 165 Broadcast(new PluginHostMsg_PluginShuttingDown());
161 } 166 }
162 167
163 PluginChannel::PluginChannel()
164 : renderer_id_(-1),
165 in_send_(0),
166 incognito_(false),
167 filter_(new MessageFilter()) {
168 set_send_unblocking_only_during_unblock_dispatch();
169 ChildProcess::current()->AddRefProcess();
170 const CommandLine* command_line = CommandLine::ForCurrentProcess();
171 log_messages_ = command_line->HasSwitch(switches::kLogPluginMessages);
172 }
173
174 PluginChannel::~PluginChannel() {
175 MessageLoop::current()->PostDelayedTask(
176 FROM_HERE,
177 base::Bind(&PluginReleaseCallback),
178 base::TimeDelta::FromMinutes(kPluginReleaseTimeMinutes));
179 }
180
181 bool PluginChannel::Send(IPC::Message* msg) { 168 bool PluginChannel::Send(IPC::Message* msg) {
182 in_send_++; 169 in_send_++;
183 if (log_messages_) { 170 if (log_messages_) {
184 VLOG(1) << "sending message @" << msg << " on channel @" << this 171 VLOG(1) << "sending message @" << msg << " on channel @" << this
185 << " with type " << msg->type(); 172 << " with type " << msg->type();
186 } 173 }
187 bool result = NPChannelBase::Send(msg); 174 bool result = NPChannelBase::Send(msg);
188 in_send_--; 175 in_send_--;
189 return result; 176 return result;
190 } 177 }
191 178
192 bool PluginChannel::OnMessageReceived(const IPC::Message& msg) { 179 bool PluginChannel::OnMessageReceived(const IPC::Message& msg) {
193 if (log_messages_) { 180 if (log_messages_) {
194 VLOG(1) << "received message @" << &msg << " on channel @" << this 181 VLOG(1) << "received message @" << &msg << " on channel @" << this
195 << " with type " << msg.type(); 182 << " with type " << msg.type();
196 } 183 }
197 return NPChannelBase::OnMessageReceived(msg); 184 return NPChannelBase::OnMessageReceived(msg);
198 } 185 }
199 186
187 void PluginChannel::OnChannelError() {
188 NPChannelBase::OnChannelError();
189 CleanUp();
190 }
191
192 int PluginChannel::GenerateRouteID() {
193 static int last_id = 0;
194 return ++last_id;
195 }
196
197 base::WaitableEvent* PluginChannel::GetModalDialogEvent(
198 gfx::NativeViewId containing_window) {
199 return filter_->GetModalDialogEvent(containing_window);
200 }
201
202 PluginChannel::~PluginChannel() {
203 MessageLoop::current()->PostDelayedTask(
204 FROM_HERE,
205 base::Bind(&PluginReleaseCallback),
206 base::TimeDelta::FromMinutes(kPluginReleaseTimeMinutes));
207 }
208
209 void PluginChannel::CleanUp() {
210 // We need to clean up the stubs so that they call NPPDestroy. This will
211 // also lead to them releasing their reference on this object so that it can
212 // be deleted.
213 for (size_t i = 0; i < plugin_stubs_.size(); ++i)
214 RemoveRoute(plugin_stubs_[i]->instance_id());
215
216 // Need to addref this object temporarily because otherwise removing the last
217 // stub will cause the destructor of this object to be called, however at
218 // that point plugin_stubs_ will have one element and its destructor will be
219 // called twice.
220 scoped_refptr<PluginChannel> me(this);
221
222 plugin_stubs_.clear();
223 }
224
225 bool PluginChannel::Init(base::MessageLoopProxy* ipc_message_loop,
226 bool create_pipe_now,
227 base::WaitableEvent* shutdown_event) {
228 if (!NPChannelBase::Init(ipc_message_loop, create_pipe_now, shutdown_event))
229 return false;
230
231 channel_->AddFilter(filter_.get());
232 return true;
233 }
234
235 PluginChannel::PluginChannel()
236 : renderer_id_(-1),
237 in_send_(0),
238 incognito_(false),
239 filter_(new MessageFilter()) {
240 set_send_unblocking_only_during_unblock_dispatch();
241 ChildProcess::current()->AddRefProcess();
242 const CommandLine* command_line = CommandLine::ForCurrentProcess();
243 log_messages_ = command_line->HasSwitch(switches::kLogPluginMessages);
244 }
245
200 bool PluginChannel::OnControlMessageReceived(const IPC::Message& msg) { 246 bool PluginChannel::OnControlMessageReceived(const IPC::Message& msg) {
201 bool handled = true; 247 bool handled = true;
202 IPC_BEGIN_MESSAGE_MAP(PluginChannel, msg) 248 IPC_BEGIN_MESSAGE_MAP(PluginChannel, msg)
203 IPC_MESSAGE_HANDLER(PluginMsg_CreateInstance, OnCreateInstance) 249 IPC_MESSAGE_HANDLER(PluginMsg_CreateInstance, OnCreateInstance)
204 IPC_MESSAGE_HANDLER_DELAY_REPLY(PluginMsg_DestroyInstance, 250 IPC_MESSAGE_HANDLER_DELAY_REPLY(PluginMsg_DestroyInstance,
205 OnDestroyInstance) 251 OnDestroyInstance)
206 IPC_MESSAGE_HANDLER(PluginMsg_GenerateRouteID, OnGenerateRouteID) 252 IPC_MESSAGE_HANDLER(PluginMsg_GenerateRouteID, OnGenerateRouteID)
207 IPC_MESSAGE_HANDLER(PluginMsg_ClearSiteData, OnClearSiteData) 253 IPC_MESSAGE_HANDLER(PluginMsg_ClearSiteData, OnClearSiteData)
208 IPC_MESSAGE_UNHANDLED(handled = false) 254 IPC_MESSAGE_UNHANDLED(handled = false)
209 IPC_END_MESSAGE_MAP() 255 IPC_END_MESSAGE_MAP()
(...skipping 30 matching lines...) Expand all
240 } 286 }
241 } 287 }
242 288
243 NOTREACHED() << "Couldn't find WebPluginDelegateStub to destroy"; 289 NOTREACHED() << "Couldn't find WebPluginDelegateStub to destroy";
244 } 290 }
245 291
246 void PluginChannel::OnGenerateRouteID(int* route_id) { 292 void PluginChannel::OnGenerateRouteID(int* route_id) {
247 *route_id = GenerateRouteID(); 293 *route_id = GenerateRouteID();
248 } 294 }
249 295
250 int PluginChannel::GenerateRouteID() {
251 static int last_id = 0;
252 return ++last_id;
253 }
254
255 void PluginChannel::OnClearSiteData(const std::string& site, 296 void PluginChannel::OnClearSiteData(const std::string& site,
256 uint64 flags, 297 uint64 flags,
257 uint64 max_age) { 298 uint64 max_age) {
258 bool success = false; 299 bool success = false;
259 CommandLine* command_line = CommandLine::ForCurrentProcess(); 300 CommandLine* command_line = CommandLine::ForCurrentProcess();
260 FilePath path = command_line->GetSwitchValuePath(switches::kPluginPath); 301 FilePath path = command_line->GetSwitchValuePath(switches::kPluginPath);
261 scoped_refptr<webkit::npapi::PluginLib> plugin_lib( 302 scoped_refptr<webkit::npapi::PluginLib> plugin_lib(
262 webkit::npapi::PluginLib::CreatePluginLib(path)); 303 webkit::npapi::PluginLib::CreatePluginLib(path));
263 if (plugin_lib.get()) { 304 if (plugin_lib.get()) {
264 NPError err = plugin_lib->NP_Initialize(); 305 NPError err = plugin_lib->NP_Initialize();
265 if (err == NPERR_NO_ERROR) { 306 if (err == NPERR_NO_ERROR) {
266 const char* site_str = site.empty() ? NULL : site.c_str(); 307 const char* site_str = site.empty() ? NULL : site.c_str();
267 err = plugin_lib->NP_ClearSiteData(site_str, flags, max_age); 308 err = plugin_lib->NP_ClearSiteData(site_str, flags, max_age);
268 std::string site_name = 309 std::string site_name =
269 site.empty() ? "NULL" 310 site.empty() ? "NULL"
270 : base::StringPrintf("\"%s\"", site_str); 311 : base::StringPrintf("\"%s\"", site_str);
271 VLOG(1) << "NPP_ClearSiteData(" << site_name << ", " << flags << ", " 312 VLOG(1) << "NPP_ClearSiteData(" << site_name << ", " << flags << ", "
272 << max_age << ") returned " << err; 313 << max_age << ") returned " << err;
273 success = (err == NPERR_NO_ERROR); 314 success = (err == NPERR_NO_ERROR);
274 } 315 }
275 } 316 }
276 Send(new PluginHostMsg_ClearSiteDataResult(success)); 317 Send(new PluginHostMsg_ClearSiteDataResult(success));
277 } 318 }
278
279 base::WaitableEvent* PluginChannel::GetModalDialogEvent(
280 gfx::NativeViewId containing_window) {
281 return filter_->GetModalDialogEvent(containing_window);
282 }
283
284 void PluginChannel::OnChannelError() {
285 NPChannelBase::OnChannelError();
286 CleanUp();
287 }
288
289 void PluginChannel::CleanUp() {
290 // We need to clean up the stubs so that they call NPPDestroy. This will
291 // also lead to them releasing their reference on this object so that it can
292 // be deleted.
293 for (size_t i = 0; i < plugin_stubs_.size(); ++i)
294 RemoveRoute(plugin_stubs_[i]->instance_id());
295
296 // Need to addref this object temporarily because otherwise removing the last
297 // stub will cause the destructor of this object to be called, however at
298 // that point plugin_stubs_ will have one element and its destructor will be
299 // called twice.
300 scoped_refptr<PluginChannel> me(this);
301
302 plugin_stubs_.clear();
303 }
304
305 bool PluginChannel::Init(base::MessageLoopProxy* ipc_message_loop,
306 bool create_pipe_now,
307 base::WaitableEvent* shutdown_event) {
308 if (!NPChannelBase::Init(ipc_message_loop, create_pipe_now, shutdown_event))
309 return false;
310
311 channel_->AddFilter(filter_.get());
312 return true;
313 }
314
OLDNEW
« no previous file with comments | « content/plugin/plugin_channel.h ('k') | content/plugin/plugin_thread.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698