summaryrefslogtreecommitdiffstats
path: root/WebCore/storage/DatabaseTracker.h
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/storage/DatabaseTracker.h')
-rw-r--r--WebCore/storage/DatabaseTracker.h56
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*);