diff options
Diffstat (limited to 'WebCore/storage/DatabaseTracker.h')
-rw-r--r-- | WebCore/storage/DatabaseTracker.h | 56 |
1 files changed, 38 insertions, 18 deletions
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<RefPtr<Database> >* 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<RefPtr<SecurityOrigin> >& result); bool databaseNamesForOrigin(SecurityOrigin*, Vector<String>& 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<String>& 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<RefPtr<SecurityOrigin>, unsigned long long, SecurityOriginHash> QuotaMap; - Mutex m_quotaMapGuard; mutable OwnPtr<QuotaMap> m_quotaMap; - OwnPtr<OriginQuotaManager> m_quotaManager; - String m_databaseDirectoryPath; DatabaseTrackerClient* m_client; - std::pair<SecurityOrigin*, DatabaseDetails>* m_proposedDatabase; - -#ifndef NDEBUG - ThreadIdentifier m_thread; -#endif + typedef std::pair<RefPtr<SecurityOrigin>, DatabaseDetails> ProposedDatabase; + HashSet<ProposedDatabase*> m_proposedDatabases; + + typedef HashMap<String, long> NameCountMap; + typedef HashMap<RefPtr<SecurityOrigin>, NameCountMap*, SecurityOriginHash> CreateSet; + CreateSet m_beingCreated; + typedef HashSet<String> NameSet; + HashMap<RefPtr<SecurityOrigin>, NameSet*, SecurityOriginHash> m_beingDeleted; + HashSet<RefPtr<SecurityOrigin>, 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*); |