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

Side by Side Diff: WebCore/storage/Database.cpp

Issue 596028: Make the DatabaseTracker thread-safe. (Closed) Base URL: http://svn.webkit.org/repository/webkit/trunk/
Patch Set: '' Created 10 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
« no previous file with comments | « WebCore/storage/Database.h ('k') | WebCore/storage/DatabaseTask.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. 2 * Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 7 *
8 * 1. Redistributions of source code must retain the above copyright 8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright 10 * 2. Redistributions in binary form must reproduce the above copyright
(...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after
345 return; 345 return;
346 } 346 }
347 347
348 m_scriptExecutionContext->databaseThread()->unscheduleDatabaseTasks(this); 348 m_scriptExecutionContext->databaseThread()->unscheduleDatabaseTasks(this);
349 349
350 DatabaseTaskSynchronizer synchronizer; 350 DatabaseTaskSynchronizer synchronizer;
351 OwnPtr<DatabaseCloseTask> task = DatabaseCloseTask::create(this, &synchroniz er); 351 OwnPtr<DatabaseCloseTask> task = DatabaseCloseTask::create(this, &synchroniz er);
352 352
353 m_scriptExecutionContext->databaseThread()->scheduleImmediateTask(task.relea se()); 353 m_scriptExecutionContext->databaseThread()->scheduleImmediateTask(task.relea se());
354 synchronizer.waitForTaskCompletion(); 354 synchronizer.waitForTaskCompletion();
355
356 // DatabaseCloseTask tells Database::close not to do this, so that we can ge t it over with here.
357 m_scriptExecutionContext->removeOpenDatabase(this);
358 DatabaseTracker::tracker().removeOpenDatabase(this);
355 } 359 }
356 360
357 class ContextRemoveOpenDatabaseTask : public ScriptExecutionContext::Task { 361 class ContextRemoveOpenDatabaseTask : public ScriptExecutionContext::Task {
358 public: 362 public:
359 static PassOwnPtr<ContextRemoveOpenDatabaseTask> create(PassRefPtr<Database> database) 363 static PassOwnPtr<ContextRemoveOpenDatabaseTask> create(PassRefPtr<Database> database)
360 { 364 {
361 return new ContextRemoveOpenDatabaseTask(database); 365 return new ContextRemoveOpenDatabaseTask(database);
362 } 366 }
363 367
364 virtual void performTask(ScriptExecutionContext* context) 368 virtual void performTask(ScriptExecutionContext* context)
365 { 369 {
366 context->removeOpenDatabase(m_database.get()); 370 context->removeOpenDatabase(m_database.get());
367 DatabaseTracker::tracker().removeOpenDatabase(m_database.get()); 371 DatabaseTracker::tracker().removeOpenDatabase(m_database.get());
368 } 372 }
369 373
370 virtual bool isCleanupTask() const { return true; } 374 virtual bool isCleanupTask() const { return true; }
371 375
372 private: 376 private:
373 ContextRemoveOpenDatabaseTask(PassRefPtr<Database> database) 377 ContextRemoveOpenDatabaseTask(PassRefPtr<Database> database)
374 : m_database(database) 378 : m_database(database)
375 { 379 {
376 } 380 }
377 381
378 RefPtr<Database> m_database; 382 RefPtr<Database> m_database;
379 }; 383 };
380 384
381 void Database::close() 385 void Database::close(bool removeDatabaseFromContext)
382 { 386 {
383 RefPtr<Database> protect = this; 387 RefPtr<Database> protect = this;
384 388
385 if (!m_opened) 389 if (!m_opened)
386 return; 390 return;
387 391
388 ASSERT(m_scriptExecutionContext->databaseThread()); 392 ASSERT(m_scriptExecutionContext->databaseThread());
389 ASSERT(currentThread() == m_scriptExecutionContext->databaseThread()->getThr eadID()); 393 ASSERT(currentThread() == m_scriptExecutionContext->databaseThread()->getThr eadID());
390 m_sqliteDatabase.close(); 394 m_sqliteDatabase.close();
391 // Must ref() before calling databaseThread()->recordDatabaseClosed(). 395 // Must ref() before calling databaseThread()->recordDatabaseClosed().
392 m_scriptExecutionContext->databaseThread()->recordDatabaseClosed(this); 396 m_scriptExecutionContext->databaseThread()->recordDatabaseClosed(this);
393 m_opened = false; 397 m_opened = false;
394 398
395 { 399 {
396 MutexLocker locker(guidMutex()); 400 MutexLocker locker(guidMutex());
397 401
398 HashSet<Database*>* hashSet = guidToDatabaseMap().get(m_guid); 402 HashSet<Database*>* hashSet = guidToDatabaseMap().get(m_guid);
399 ASSERT(hashSet); 403 ASSERT(hashSet);
400 ASSERT(hashSet->contains(this)); 404 ASSERT(hashSet->contains(this));
401 hashSet->remove(this); 405 hashSet->remove(this);
402 if (hashSet->isEmpty()) { 406 if (hashSet->isEmpty()) {
403 guidToDatabaseMap().remove(m_guid); 407 guidToDatabaseMap().remove(m_guid);
404 delete hashSet; 408 delete hashSet;
405 guidToVersionMap().remove(m_guid); 409 guidToVersionMap().remove(m_guid);
406 } 410 }
407 } 411 }
408 412
409 m_scriptExecutionContext->databaseThread()->unscheduleDatabaseTasks(this); 413 m_scriptExecutionContext->databaseThread()->unscheduleDatabaseTasks(this);
410 m_scriptExecutionContext->postTask(ContextRemoveOpenDatabaseTask::create(thi s)); 414 // In some cases the context initiated this call, so it'll take care of the cleanup by itself, synchronously. This lets it make sure that the
415 // cleanup completes by a given time.
416 if (removeDatabaseFromContext)
417 m_scriptExecutionContext->postTask(ContextRemoveOpenDatabaseTask::create (this));
411 } 418 }
412 419
413 void Database::stop() 420 void Database::stop()
414 { 421 {
415 // FIXME: The net effect of the following code is to remove all pending tran sactions and statements, but allow the current statement 422 // FIXME: The net effect of the following code is to remove all pending tran sactions and statements, but allow the current statement
416 // to run to completion. In the future we can use the sqlite3_progress_hand ler or sqlite3_interrupt interfaces to cancel the current 423 // to run to completion. In the future we can use the sqlite3_progress_hand ler or sqlite3_interrupt interfaces to cancel the current
417 // statement in response to close(), as well. 424 // statement in response to close(), as well.
418 425
419 // This method is meant to be used as an analog to cancelling a loader, and is used when a document is shut down as the result of 426 // This method is meant to be used as an analog to cancelling a loader, and is used when a document is shut down as the result of
420 // a page load or closing the page 427 // a page load or closing the page
(...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after
756 763
757 String Database::fileName() const 764 String Database::fileName() const
758 { 765 {
759 // Return a deep copy for ref counting thread safety 766 // Return a deep copy for ref counting thread safety
760 return m_filename.threadsafeCopy(); 767 return m_filename.threadsafeCopy();
761 } 768 }
762 769
763 #endif // ENABLE(DATABASE) 770 #endif // ENABLE(DATABASE)
764 771
765 } // namespace WebCore 772 } // namespace WebCore
OLDNEW
« no previous file with comments | « WebCore/storage/Database.h ('k') | WebCore/storage/DatabaseTask.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698