| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |