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

Side by Side Diff: content/browser/in_process_webkit/indexed_db_key_utility_client.cc

Issue 9235052: Fix race condition in utility process clients (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: sync to ToT Created 8 years, 10 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
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/in_process_webkit/indexed_db_key_utility_client.h" 5 #include "content/browser/in_process_webkit/indexed_db_key_utility_client.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/lazy_instance.h" 8 #include "base/lazy_instance.h"
9 #include "base/synchronization/waitable_event.h" 9 #include "base/synchronization/waitable_event.h"
10 #include "content/browser/utility_process_host.h" 10 #include "content/browser/utility_process_host.h"
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
93 STATE_INITIALIZED, 93 STATE_INITIALIZED,
94 STATE_CREATING_KEYS, 94 STATE_CREATING_KEYS,
95 STATE_INJECTING_KEY, 95 STATE_INJECTING_KEY,
96 STATE_SHUTDOWN, 96 STATE_SHUTDOWN,
97 }; 97 };
98 State state_; 98 State state_;
99 std::vector<IndexedDBKey> keys_; 99 std::vector<IndexedDBKey> keys_;
100 content::SerializedScriptValue value_after_injection_; 100 content::SerializedScriptValue value_after_injection_;
101 101
102 // Used in the IO thread. 102 // Used in the IO thread.
103 UtilityProcessHost* utility_process_host_; 103 base::WeakPtr<UtilityProcessHost> utility_process_host_;
104 scoped_refptr<Client> client_; 104 scoped_refptr<Client> client_;
105 105
106 DISALLOW_COPY_AND_ASSIGN(KeyUtilityClientImpl); 106 DISALLOW_COPY_AND_ASSIGN(KeyUtilityClientImpl);
107 }; 107 };
108 108
109 // IndexedDBKeyUtilityClient definitions. 109 // IndexedDBKeyUtilityClient definitions.
110 110
111 static base::LazyInstance<IndexedDBKeyUtilityClient> client_instance = 111 static base::LazyInstance<IndexedDBKeyUtilityClient> client_instance =
112 LAZY_INSTANCE_INITIALIZER; 112 LAZY_INSTANCE_INITIALIZER;
113 113
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
170 return instance->impl_->InjectIDBKeyIntoSerializedValue(key, value, key_path); 170 return instance->impl_->InjectIDBKeyIntoSerializedValue(key, value, key_path);
171 } 171 }
172 172
173 173
174 174
175 // KeyUtilityClientImpl definitions. 175 // KeyUtilityClientImpl definitions.
176 176
177 void KeyUtilityClientImpl::Shutdown() { 177 void KeyUtilityClientImpl::Shutdown() {
178 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 178 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
179 179
180 utility_process_host_->EndBatchMode(); 180 if (utility_process_host_) {
181 utility_process_host_ = NULL; 181 utility_process_host_->EndBatchMode();
182 utility_process_host_.reset();
183 }
182 client_ = NULL; 184 client_ = NULL;
183 state_ = STATE_SHUTDOWN; 185 state_ = STATE_SHUTDOWN;
184 } 186 }
185 187
186 KeyUtilityClientImpl::KeyUtilityClientImpl() 188 KeyUtilityClientImpl::KeyUtilityClientImpl()
187 : waitable_event_(false, false), 189 : waitable_event_(false, false),
188 state_(STATE_UNINITIALIZED), 190 state_(STATE_UNINITIALIZED) {
189 utility_process_host_(NULL) {
190 } 191 }
191 192
192 KeyUtilityClientImpl::~KeyUtilityClientImpl() { 193 KeyUtilityClientImpl::~KeyUtilityClientImpl() {
193 DCHECK(state_ == STATE_UNINITIALIZED || state_ == STATE_SHUTDOWN); 194 DCHECK(state_ == STATE_UNINITIALIZED || state_ == STATE_SHUTDOWN);
194 DCHECK(!utility_process_host_); 195 DCHECK(!utility_process_host_);
195 DCHECK(!client_.get()); 196 DCHECK(!client_.get());
196 } 197 }
197 198
198 void KeyUtilityClientImpl::StartUtilityProcess() { 199 void KeyUtilityClientImpl::StartUtilityProcess() {
199 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED)); 200 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT_DEPRECATED));
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
267 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 268 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
268 BrowserThread::PostTask( 269 BrowserThread::PostTask(
269 BrowserThread::IO, FROM_HERE, 270 BrowserThread::IO, FROM_HERE,
270 base::Bind(&KeyUtilityClientImpl::StartUtilityProcessInternal, this)); 271 base::Bind(&KeyUtilityClientImpl::StartUtilityProcessInternal, this));
271 return; 272 return;
272 } 273 }
273 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 274 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
274 DCHECK(state_ == STATE_UNINITIALIZED); 275 DCHECK(state_ == STATE_UNINITIALIZED);
275 276
276 client_ = new KeyUtilityClientImpl::Client(this); 277 client_ = new KeyUtilityClientImpl::Client(this);
277 utility_process_host_ = new UtilityProcessHost( 278 utility_process_host_ = (new UtilityProcessHost(
278 client_.get(), BrowserThread::IO); 279 client_.get(), BrowserThread::IO))->AsWeakPtr();
279 utility_process_host_->set_use_linux_zygote(true); 280 utility_process_host_->set_use_linux_zygote(true);
280 utility_process_host_->StartBatchMode(); 281 utility_process_host_->StartBatchMode();
281 state_ = STATE_INITIALIZED; 282 state_ = STATE_INITIALIZED;
282 waitable_event_.Signal(); 283 waitable_event_.Signal();
283 } 284 }
284 285
285 void KeyUtilityClientImpl::EndUtilityProcessInternal() { 286 void KeyUtilityClientImpl::EndUtilityProcessInternal() {
286 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { 287 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
287 BrowserThread::PostTask( 288 BrowserThread::PostTask(
288 BrowserThread::IO, FROM_HERE, 289 BrowserThread::IO, FROM_HERE,
289 base::Bind(&KeyUtilityClientImpl::EndUtilityProcessInternal, this)); 290 base::Bind(&KeyUtilityClientImpl::EndUtilityProcessInternal, this));
290 return; 291 return;
291 } 292 }
292 293
293 utility_process_host_->EndBatchMode(); 294 if (utility_process_host_) {
294 utility_process_host_ = NULL; 295 utility_process_host_->EndBatchMode();
296 utility_process_host_.reset();
297 }
295 client_ = NULL; 298 client_ = NULL;
296 state_ = STATE_SHUTDOWN; 299 state_ = STATE_SHUTDOWN;
297 waitable_event_.Signal(); 300 waitable_event_.Signal();
298 } 301 }
299 302
300 void KeyUtilityClientImpl::CallStartIDBKeyFromValueAndKeyPathFromIOThread( 303 void KeyUtilityClientImpl::CallStartIDBKeyFromValueAndKeyPathFromIOThread(
301 const std::vector<content::SerializedScriptValue>& values, 304 const std::vector<content::SerializedScriptValue>& values,
302 const string16& key_path) { 305 const string16& key_path) {
303 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { 306 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
304 BrowserThread::PostTask( 307 BrowserThread::PostTask(
305 BrowserThread::IO, FROM_HERE, 308 BrowserThread::IO, FROM_HERE,
306 base::Bind(&KeyUtilityClientImpl:: 309 base::Bind(&KeyUtilityClientImpl::
307 CallStartIDBKeyFromValueAndKeyPathFromIOThread, 310 CallStartIDBKeyFromValueAndKeyPathFromIOThread,
308 this, values, key_path)); 311 this, values, key_path));
309 return; 312 return;
310 } 313 }
311 314
312 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 315 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
313 utility_process_host_->Send(new UtilityMsg_IDBKeysFromValuesAndKeyPath( 316 if (utility_process_host_) {
314 0, values, key_path)); 317 utility_process_host_->Send(new UtilityMsg_IDBKeysFromValuesAndKeyPath(
318 0, values, key_path));
319 }
315 } 320 }
316 321
317 void KeyUtilityClientImpl::CallStartInjectIDBKeyFromIOThread( 322 void KeyUtilityClientImpl::CallStartInjectIDBKeyFromIOThread(
318 const IndexedDBKey& key, 323 const IndexedDBKey& key,
319 const content::SerializedScriptValue& value, 324 const content::SerializedScriptValue& value,
320 const string16& key_path) { 325 const string16& key_path) {
321 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) { 326 if (!BrowserThread::CurrentlyOn(BrowserThread::IO)) {
322 BrowserThread::PostTask( 327 BrowserThread::PostTask(
323 BrowserThread::IO, FROM_HERE, 328 BrowserThread::IO, FROM_HERE,
324 base::Bind(&KeyUtilityClientImpl::CallStartInjectIDBKeyFromIOThread, 329 base::Bind(&KeyUtilityClientImpl::CallStartInjectIDBKeyFromIOThread,
325 this, key, value, key_path)); 330 this, key, value, key_path));
326 return; 331 return;
327 } 332 }
328 333
329 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 334 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
330 utility_process_host_->Send(new UtilityMsg_InjectIDBKey( 335 if (utility_process_host_)
331 key, value, key_path)); 336 utility_process_host_->Send(new UtilityMsg_InjectIDBKey(
337 key, value, key_path));
332 } 338 }
333 339
334 void KeyUtilityClientImpl::SetKeys(const std::vector<IndexedDBKey>& keys) { 340 void KeyUtilityClientImpl::SetKeys(const std::vector<IndexedDBKey>& keys) {
335 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); 341 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
336 keys_ = keys; 342 keys_ = keys;
337 } 343 }
338 344
339 void KeyUtilityClientImpl::FinishCreatingKeys() { 345 void KeyUtilityClientImpl::FinishCreatingKeys() {
340 DCHECK(state_ == STATE_CREATING_KEYS); 346 DCHECK(state_ == STATE_CREATING_KEYS);
341 state_ = STATE_INITIALIZED; 347 state_ = STATE_INITIALIZED;
(...skipping 12 matching lines...) Expand all
354 waitable_event_.Signal(); 360 waitable_event_.Signal();
355 } 361 }
356 362
357 KeyUtilityClientImpl::Client::Client(KeyUtilityClientImpl* parent) 363 KeyUtilityClientImpl::Client::Client(KeyUtilityClientImpl* parent)
358 : parent_(parent) { 364 : parent_(parent) {
359 } 365 }
360 366
361 void KeyUtilityClientImpl::Client::OnProcessCrashed(int exit_code) { 367 void KeyUtilityClientImpl::Client::OnProcessCrashed(int exit_code) {
362 if (parent_->state_ == STATE_CREATING_KEYS) 368 if (parent_->state_ == STATE_CREATING_KEYS)
363 parent_->FinishCreatingKeys(); 369 parent_->FinishCreatingKeys();
370 parent_->Shutdown();
364 } 371 }
365 372
366 bool KeyUtilityClientImpl::Client::OnMessageReceived( 373 bool KeyUtilityClientImpl::Client::OnMessageReceived(
367 const IPC::Message& message) { 374 const IPC::Message& message) {
368 bool handled = true; 375 bool handled = true;
369 IPC_BEGIN_MESSAGE_MAP(KeyUtilityClientImpl::Client, message) 376 IPC_BEGIN_MESSAGE_MAP(KeyUtilityClientImpl::Client, message)
370 IPC_MESSAGE_HANDLER(UtilityHostMsg_IDBKeysFromValuesAndKeyPath_Succeeded, 377 IPC_MESSAGE_HANDLER(UtilityHostMsg_IDBKeysFromValuesAndKeyPath_Succeeded,
371 OnIDBKeysFromValuesAndKeyPathSucceeded) 378 OnIDBKeysFromValuesAndKeyPathSucceeded)
372 IPC_MESSAGE_HANDLER(UtilityHostMsg_IDBKeysFromValuesAndKeyPath_Failed, 379 IPC_MESSAGE_HANDLER(UtilityHostMsg_IDBKeysFromValuesAndKeyPath_Failed,
373 OnIDBKeysFromValuesAndKeyPathFailed) 380 OnIDBKeysFromValuesAndKeyPathFailed)
(...skipping 13 matching lines...) Expand all
387 void KeyUtilityClientImpl::Client::OnInjectIDBKeyFinished( 394 void KeyUtilityClientImpl::Client::OnInjectIDBKeyFinished(
388 const content::SerializedScriptValue& value) { 395 const content::SerializedScriptValue& value) {
389 parent_->SetValueAfterInjection(value); 396 parent_->SetValueAfterInjection(value);
390 parent_->FinishInjectingKey(); 397 parent_->FinishInjectingKey();
391 } 398 }
392 399
393 void KeyUtilityClientImpl::Client::OnIDBKeysFromValuesAndKeyPathFailed( 400 void KeyUtilityClientImpl::Client::OnIDBKeysFromValuesAndKeyPathFailed(
394 int id) { 401 int id) {
395 parent_->FinishCreatingKeys(); 402 parent_->FinishCreatingKeys();
396 } 403 }
OLDNEW
« no previous file with comments | « content/browser/browser_child_process_host_impl.cc ('k') | content/browser/indexed_db/idbbindingutilities_browsertest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698