Bug 519769 - Open shared/unshared connection with options instead of setting shared state always

Use the flags SQLite provides on sqlite3_open_v2 instead of using a mutex to
protect the shared cache state.
r=asuth
a=gavin
This commit is contained in:
Shawn Wilsher 2010-08-27 12:42:55 -07:00
parent b3b7f224fd
commit d6bf9c5574
3 changed files with 18 additions and 38 deletions

View File

@ -353,7 +353,8 @@ Connection::getAsyncExecutionTarget()
}
nsresult
Connection::initialize(nsIFile *aDatabaseFile)
Connection::initialize(nsIFile *aDatabaseFile,
int aFlags)
{
NS_ASSERTION (!mDBConn, "Initialize called on already opened database!");
@ -362,16 +363,20 @@ Connection::initialize(nsIFile *aDatabaseFile)
mDatabaseFile = aDatabaseFile;
// Always ensure that SQLITE_OPEN_CREATE is passed in for compatibility
// reasons.
int flags = aFlags | SQLITE_OPEN_CREATE;
if (aDatabaseFile) {
nsAutoString path;
rv = aDatabaseFile->GetPath(path);
NS_ENSURE_SUCCESS(rv, rv);
srv = ::sqlite3_open(NS_ConvertUTF16toUTF8(path).get(), &mDBConn);
srv = ::sqlite3_open_v2(NS_ConvertUTF16toUTF8(path).get(), &mDBConn, flags,
NULL);
}
else {
// in memory database requested, sqlite uses a magic file name
srv = ::sqlite3_open(":memory:", &mDBConn);
srv = ::sqlite3_open_v2(":memory:", &mDBConn, flags, NULL);
}
if (srv != SQLITE_OK) {
mDBConn = nsnull;

View File

@ -79,8 +79,11 @@ public:
* The nsIFile of the location of the database to open, or create if it
* does not exist. Passing in nsnull here creates an in-memory
* database.
* @param aFlags
* The flags to pass to sqlite3_open_v2. For compatibility reasons,
* We always pass SQLITE_OPEN_CREATE to sqlite3_open_v2.
*/
nsresult initialize(nsIFile *aDatabaseFile);
nsresult initialize(nsIFile *aDatabaseFile, int aFlags);
// fetch the native handle
sqlite3 *GetNativeConnection() { return mDBConn; }

View File

@ -248,15 +248,6 @@ Service::initialize()
if (rc != SQLITE_OK)
return convertResultCode(rc);
// This makes multiple connections to the same database share the same pager
// cache. We do not need to lock here with mMutex because this function is
// only ever called from Service::GetSingleton, which will only
// call this function once, and will not return until this function returns.
// (It does not matter where this is called relative to sqlite3_initialize.)
rc = ::sqlite3_enable_shared_cache(1);
if (rc != SQLITE_OK)
return convertResultCode(rc);
// Run the things that need to run on the main thread there.
nsCOMPtr<nsIRunnable> event =
new ServiceMainThreadInitializer(this, &sXPConnect);
@ -369,7 +360,7 @@ Service::OpenSpecialDatabase(const char *aStorageKey,
Connection *msc = new Connection(this);
NS_ENSURE_TRUE(msc, NS_ERROR_OUT_OF_MEMORY);
rv = msc->initialize(storageFile);
rv = msc->initialize(storageFile, SQLITE_OPEN_READWRITE);
NS_ENSURE_SUCCESS(rv, rv);
NS_ADDREF(*_connection = msc);
@ -391,11 +382,9 @@ Service::OpenDatabase(nsIFile *aDatabaseFile,
nsRefPtr<Connection> msc = new Connection(this);
NS_ENSURE_TRUE(msc, NS_ERROR_OUT_OF_MEMORY);
{
MutexAutoLock mutex(mMutex);
nsresult rv = msc->initialize(aDatabaseFile);
NS_ENSURE_SUCCESS(rv, rv);
}
int flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_SHAREDCACHE;
nsresult rv = msc->initialize(aDatabaseFile, flags);
NS_ENSURE_SUCCESS(rv, rv);
NS_ADDREF(*_connection = msc);
return NS_OK;
@ -415,25 +404,8 @@ Service::OpenUnsharedDatabase(nsIFile *aDatabaseFile,
nsRefPtr<Connection> msc = new Connection(this);
NS_ENSURE_TRUE(msc, NS_ERROR_OUT_OF_MEMORY);
// Initialize the connection, temporarily turning off shared caches so the
// new connection gets its own cache. Database connections are assigned
// caches when they are opened, and they retain those caches for their
// lifetimes, unaffected by changes to the shared caches setting, so we can
// disable shared caches temporarily while we initialize the new connection
// without affecting the caches currently in use by other connections.
nsresult rv;
{
MutexAutoLock mutex(mMutex);
int rc = ::sqlite3_enable_shared_cache(0);
if (rc != SQLITE_OK)
return convertResultCode(rc);
rv = msc->initialize(aDatabaseFile);
rc = ::sqlite3_enable_shared_cache(1);
if (rc != SQLITE_OK)
return convertResultCode(rc);
}
int flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_PRIVATECACHE;
nsresult rv = msc->initialize(aDatabaseFile, flags);
NS_ENSURE_SUCCESS(rv, rv);
NS_ADDREF(*_connection = msc);