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 |