From dcc8cf2e65d1aa555cce12431a16547e66b469ee Mon Sep 17 00:00:00 2001 From: Steve Block Date: Tue, 27 Apr 2010 16:31:00 +0100 Subject: Merge webkit.org at r58033 : Initial merge by git Change-Id: If006c38561af287c50cd578d251629b51e4d8cd1 --- WebCore/storage/DatabaseTracker.h | 56 ++++++++++++++++++++++++++------------- 1 file changed, 38 insertions(+), 18 deletions(-) (limited to 'WebCore/storage/DatabaseTracker.h') diff --git a/WebCore/storage/DatabaseTracker.h b/WebCore/storage/DatabaseTracker.h index 4640b18..fdfbb65 100644 --- a/WebCore/storage/DatabaseTracker.h +++ b/WebCore/storage/DatabaseTracker.h @@ -52,7 +52,6 @@ struct SecurityOriginHash; #if !PLATFORM(CHROMIUM) class DatabaseTrackerClient; -class OriginQuotaManager; struct SecurityOriginTraits; #endif // !PLATFORM(CHROMIUM) @@ -60,9 +59,11 @@ struct SecurityOriginTraits; class DatabaseTracker : public Noncopyable { public: static DatabaseTracker& tracker(); - // FIXME: Due to workers having multiple threads in a single process sharing - // a DatabaseTracker, this singleton will have to be synchronized or moved - // to TLS. + // This singleton will potentially be used from multiple worker threads and the page's context thread simultaneously. To keep this safe, it's + // currently using 4 locks. In order to avoid deadlock when taking multiple locks, you must take them in the correct order: + // m_databaseGuard before quotaManager if both locks are needed. + // no other lock is taken in the code locked on m_openDatabaseMapGuard. + // notificationMutex() is currently independent of the other locks. bool canEstablishDatabase(ScriptExecutionContext*, const String& name, const String& displayName, unsigned long estimatedSize); void setDatabaseDetails(SecurityOrigin*, const String& name, const String& displayName, unsigned long estimatedSize); @@ -73,6 +74,7 @@ public: void getOpenDatabases(SecurityOrigin* origin, const String& name, HashSet >* databases); unsigned long long getMaxSizeForDatabase(const Database*); + void databaseChanged(Database*); private: DatabaseTracker(); @@ -87,7 +89,7 @@ private: #if !PLATFORM(CHROMIUM) public: void setDatabaseDirectoryPath(const String&); - const String& databaseDirectoryPath() const; + String databaseDirectoryPath() const; void origins(Vector >& result); bool databaseNamesForOrigin(SecurityOrigin*, Vector& result); @@ -100,20 +102,23 @@ public: void setQuota(SecurityOrigin*, unsigned long long); void deleteAllDatabases(); - void deleteOrigin(SecurityOrigin*); - void deleteDatabase(SecurityOrigin*, const String& name); + bool deleteOrigin(SecurityOrigin*); + bool deleteDatabase(SecurityOrigin*, const String& name); void setClient(DatabaseTrackerClient*); // From a secondary thread, must be thread safe with its data void scheduleNotifyDatabaseChanged(SecurityOrigin*, const String& name); - OriginQuotaManager& originQuotaManager(); - - bool hasEntryForOrigin(SecurityOrigin*); private: + bool hasEntryForOriginNoLock(SecurityOrigin* origin); + String fullPathForDatabaseNoLock(SecurityOrigin*, const String& name, bool createIfDoesNotExist); + bool databaseNamesForOriginNoLock(SecurityOrigin* origin, Vector& resultVector); + unsigned long long usageForOriginNoLock(SecurityOrigin* origin); + unsigned long long quotaForOriginNoLock(SecurityOrigin* origin); + String trackerDatabasePath() const; void openTrackerDatabase(bool createIfDoesNotExist); @@ -126,23 +131,38 @@ private: bool deleteDatabaseFile(SecurityOrigin*, const String& name); + // This lock protects m_database, m_quotaMap, m_proposedDatabases, m_databaseDirectoryPath, m_originsBeingDeleted, m_beingCreated, and m_beingDeleted. + Mutex m_databaseGuard; SQLiteDatabase m_database; typedef HashMap, unsigned long long, SecurityOriginHash> QuotaMap; - Mutex m_quotaMapGuard; mutable OwnPtr m_quotaMap; - OwnPtr m_quotaManager; - String m_databaseDirectoryPath; DatabaseTrackerClient* m_client; - std::pair* m_proposedDatabase; - -#ifndef NDEBUG - ThreadIdentifier m_thread; -#endif + typedef std::pair, DatabaseDetails> ProposedDatabase; + HashSet m_proposedDatabases; + + typedef HashMap NameCountMap; + typedef HashMap, NameCountMap*, SecurityOriginHash> CreateSet; + CreateSet m_beingCreated; + typedef HashSet NameSet; + HashMap, NameSet*, SecurityOriginHash> m_beingDeleted; + HashSet, SecurityOriginHash> m_originsBeingDeleted; + bool canCreateDatabase(SecurityOrigin *origin, const String& name); + void recordCreatingDatabase(SecurityOrigin *origin, const String& name); + void doneCreatingDatabase(SecurityOrigin *origin, const String& name); + bool creatingDatabase(SecurityOrigin *origin, const String& name); + bool canDeleteDatabase(SecurityOrigin *origin, const String& name); + void recordDeletingDatabase(SecurityOrigin *origin, const String& name); + void doneDeletingDatabase(SecurityOrigin *origin, const String& name); + bool deletingDatabase(SecurityOrigin *origin, const String& name); + bool canDeleteOrigin(SecurityOrigin *origin); + bool deletingOrigin(SecurityOrigin *origin); + void recordDeletingOrigin(SecurityOrigin *origin); + void doneDeletingOrigin(SecurityOrigin *origin); static void scheduleForNotification(); static void notifyDatabasesChanged(void*); -- cgit v1.1