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

Side by Side Diff: content/browser/plugin_data_remover_impl.cc

Issue 8603012: Fix race in PluginDataRemoverImpl going away while it's still being used on the IO thread... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years, 1 month 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
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 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 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/browser/plugin_data_remover_impl.h" 5 #include "content/browser/plugin_data_remover_impl.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/metrics/histogram.h" 8 #include "base/metrics/histogram.h"
9 #include "base/synchronization/waitable_event.h" 9 #include "base/synchronization/waitable_event.h"
10 #include "base/version.h" 10 #include "base/version.h"
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
47 scoped_ptr<Version> min_version( 47 scoped_ptr<Version> min_version(
48 Version::GetVersionFromString(kMinFlashVersion)); 48 Version::GetVersionFromString(kMinFlashVersion));
49 bool rv = version.get() && min_version->CompareTo(*version) == -1; 49 bool rv = version.get() && min_version->CompareTo(*version) == -1;
50 if (rv) 50 if (rv)
51 *plugin = *plugin_it; 51 *plugin = *plugin_it;
52 return rv; 52 return rv;
53 } 53 }
54 54
55 } 55 }
56 56
57 PluginDataRemoverImpl::PluginDataRemoverImpl( 57 PluginDataRemoverImpl::Context::Context(
58 const std::string& mime_type,
59 base::Time begin_time,
58 const content::ResourceContext& resource_context) 60 const content::ResourceContext& resource_context)
59 : mime_type_(kFlashMimeType), 61 : event_(new base::WaitableEvent(true, false)),
60 is_starting_process_(false), 62 begin_time_(begin_time),
61 is_removing_(false), 63 is_removing_(false),
62 context_(resource_context), 64 resource_context_(resource_context),
63 event_(new base::WaitableEvent(true, false)), 65 channel_(NULL) {
64 channel_(NULL), 66 // Balanced in OnChannelOpened or OnError. Exactly one them will eventually be
65 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) { 67 // called, so we need to keep this object around until then.
68 AddRef();
69 remove_start_time_ = base::Time::Now();
70 BrowserThread::PostTask(
71 BrowserThread::IO,
72 FROM_HERE,
73 base::Bind(&Context::Init, this, mime_type));
74
75 BrowserThread::PostDelayedTask(
76 BrowserThread::IO,
77 FROM_HERE,
78 base::Bind(&Context::OnTimeout, this),
79 kRemovalTimeoutMs);
66 } 80 }
67 81
68 PluginDataRemoverImpl::~PluginDataRemoverImpl() { 82 PluginDataRemoverImpl::Context::~Context() {
69 if (is_starting_process_)
70 PluginService::GetInstance()->CancelOpenChannelToNpapiPlugin(this);
71 DCHECK(!is_removing_);
72 if (channel_) 83 if (channel_)
73 BrowserThread::DeleteSoon(BrowserThread::IO, FROM_HERE, channel_); 84 BrowserThread::DeleteSoon(BrowserThread::IO, FROM_HERE, channel_);
74 } 85 }
75 86
76 base::WaitableEvent* PluginDataRemoverImpl::StartRemoving( 87 void PluginDataRemoverImpl::Context::Init(const std::string& mime_type) {
77 base::Time begin_time) { 88 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
78 DCHECK(!is_removing_);
79 remove_start_time_ = base::Time::Now();
80 begin_time_ = begin_time;
81
82 is_starting_process_ = true;
83 is_removing_ = true; 89 is_removing_ = true;
84 PluginService::GetInstance()->OpenChannelToNpapiPlugin( 90 PluginService::GetInstance()->OpenChannelToNpapiPlugin(
85 0, 0, GURL(), GURL(), mime_type_, this); 91 0, 0, GURL(), GURL(), mime_type, this);
86
87 BrowserThread::PostDelayedTask(
88 BrowserThread::IO,
89 FROM_HERE,
90 base::Bind(&PluginDataRemoverImpl::OnTimeout, weak_factory_.GetWeakPtr()),
91 kRemovalTimeoutMs);
92
93 return event_.get();
94 } 92 }
95 93
96 int PluginDataRemoverImpl::ID() { 94 int PluginDataRemoverImpl::Context::ID() {
97 // Generate a unique identifier for this PluginProcessHostClient. 95 // Generate a unique identifier for this PluginProcessHostClient.
98 return ChildProcessInfo::GenerateChildProcessUniqueId(); 96 return ChildProcessInfo::GenerateChildProcessUniqueId();
99 } 97 }
100 98
101 bool PluginDataRemoverImpl::OffTheRecord() { 99 bool PluginDataRemoverImpl::Context::OffTheRecord() {
102 return false; 100 return false;
103 } 101 }
104 102
105 const content::ResourceContext& PluginDataRemoverImpl::GetResourceContext() { 103 const content::ResourceContext&
106 return context_; 104 PluginDataRemoverImpl::Context::GetResourceContext() {
105 return resource_context_;
107 } 106 }
108 107
109 void PluginDataRemoverImpl::SetPluginInfo( 108 void PluginDataRemoverImpl::Context::SetPluginInfo(
110 const webkit::WebPluginInfo& info) { 109 const webkit::WebPluginInfo& info) {
111 } 110 }
112 111
113 void PluginDataRemoverImpl::OnFoundPluginProcessHost( 112 void PluginDataRemoverImpl::Context::OnFoundPluginProcessHost(
114 PluginProcessHost* host) { 113 PluginProcessHost* host) {
115 } 114 }
116 115
117 void PluginDataRemoverImpl::OnSentPluginChannelRequest() { 116 void PluginDataRemoverImpl::Context::OnSentPluginChannelRequest() {
118 } 117 }
119 118
120 void PluginDataRemoverImpl::OnChannelOpened(const IPC::ChannelHandle& handle) { 119 void PluginDataRemoverImpl::Context::OnChannelOpened(
121 is_starting_process_ = false; 120 const IPC::ChannelHandle& handle) {
122 ConnectToChannel(handle); 121 ConnectToChannel(handle);
122 // Balancing the AddRef call.
123 Release();
123 } 124 }
124 125
125 void PluginDataRemoverImpl::ConnectToChannel(const IPC::ChannelHandle& handle) { 126 void PluginDataRemoverImpl::Context::OnError() {
127 LOG(DFATAL) << "Couldn't open plugin channel";
128 SignalDone();
129 // Balancing the AddRef call.
130 Release();
131 }
132
133 void PluginDataRemoverImpl::Context::ConnectToChannel(
134 const IPC::ChannelHandle& handle) {
126 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 135 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
127 136
128 // If we timed out, don't bother connecting. 137 // If we timed out, don't bother connecting.
129 if (!is_removing_) 138 if (!is_removing_)
130 return; 139 return;
131 140
132 DCHECK(!channel_); 141 DCHECK(!channel_);
133 channel_ = new IPC::Channel(handle, IPC::Channel::MODE_CLIENT, this); 142 channel_ = new IPC::Channel(handle, IPC::Channel::MODE_CLIENT, this);
134 if (!channel_->Connect()) { 143 if (!channel_->Connect()) {
135 NOTREACHED() << "Couldn't connect to plugin"; 144 NOTREACHED() << "Couldn't connect to plugin";
136 SignalDone(); 145 SignalDone();
137 return; 146 return;
138 } 147 }
139 148
140 if (!channel_->Send(new PluginMsg_ClearSiteData(std::string(), 149 if (!channel_->Send(new PluginMsg_ClearSiteData(std::string(),
141 kClearAllData, 150 kClearAllData,
142 begin_time_))) { 151 begin_time_))) {
143 NOTREACHED() << "Couldn't send ClearSiteData message"; 152 NOTREACHED() << "Couldn't send ClearSiteData message";
144 SignalDone(); 153 SignalDone();
145 return; 154 return;
146 } 155 }
147 } 156 }
148 157
149 void PluginDataRemoverImpl::OnError() { 158 void PluginDataRemoverImpl::Context::OnClearSiteDataResult(bool success) {
150 LOG(DFATAL) << "Couldn't open plugin channel";
151 SignalDone();
152 }
153
154 void PluginDataRemoverImpl::OnClearSiteDataResult(bool success) {
155 LOG_IF(ERROR, !success) << "ClearSiteData returned error"; 159 LOG_IF(ERROR, !success) << "ClearSiteData returned error";
156 UMA_HISTOGRAM_TIMES("ClearPluginData.time", 160 UMA_HISTOGRAM_TIMES("ClearPluginData.time",
157 base::Time::Now() - remove_start_time_); 161 base::Time::Now() - remove_start_time_);
158 SignalDone(); 162 SignalDone();
159 } 163 }
160 164
161 void PluginDataRemoverImpl::OnTimeout() { 165 void PluginDataRemoverImpl::Context::OnTimeout() {
162 LOG_IF(ERROR, is_removing_) << "Timed out"; 166 LOG_IF(ERROR, is_removing_) << "Timed out";
163 SignalDone(); 167 SignalDone();
164 } 168 }
165 169
166 bool PluginDataRemoverImpl::OnMessageReceived(const IPC::Message& msg) { 170 bool PluginDataRemoverImpl::Context::OnMessageReceived(
167 IPC_BEGIN_MESSAGE_MAP(PluginDataRemoverImpl, msg) 171 const IPC::Message& msg) {
172 IPC_BEGIN_MESSAGE_MAP(Context, msg)
168 IPC_MESSAGE_HANDLER(PluginHostMsg_ClearSiteDataResult, 173 IPC_MESSAGE_HANDLER(PluginHostMsg_ClearSiteDataResult,
169 OnClearSiteDataResult) 174 OnClearSiteDataResult)
170 IPC_MESSAGE_UNHANDLED_ERROR() 175 IPC_MESSAGE_UNHANDLED_ERROR()
171 IPC_END_MESSAGE_MAP() 176 IPC_END_MESSAGE_MAP()
172 177
173 return true; 178 return true;
174 } 179 }
175 180
176 void PluginDataRemoverImpl::OnChannelError() { 181 void PluginDataRemoverImpl::Context::OnChannelError() {
177 is_starting_process_ = false;
178 if (is_removing_) { 182 if (is_removing_) {
179 NOTREACHED() << "Channel error"; 183 NOTREACHED() << "Channel error";
180 SignalDone(); 184 SignalDone();
181 } 185 }
182 } 186 }
183 187
184 void PluginDataRemoverImpl::SignalDone() { 188 void PluginDataRemoverImpl::Context::SignalDone() {
185 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 189 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
186 if (!is_removing_) 190 if (!is_removing_)
187 return; 191 return;
188 is_removing_ = false; 192 is_removing_ = false;
189 event_->Signal(); 193 event_->Signal();
190 } 194 }
195
196
197 PluginDataRemoverImpl::PluginDataRemoverImpl(
198 const content::ResourceContext& resource_context)
199 : mime_type_(kFlashMimeType),
200 resource_context_(resource_context) {
201 }
202
203 PluginDataRemoverImpl::~PluginDataRemoverImpl() {
204 }
205
206 base::WaitableEvent* PluginDataRemoverImpl::StartRemoving(
207 base::Time begin_time) {
208 DCHECK(!context_.get());
209 context_ = new Context(mime_type_, begin_time, resource_context_);
210 return context_->event();
211 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698