diff options
author | drh <drh@noemail.net> | 2009-04-30 13:30:32 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2009-04-30 13:30:32 +0000 |
commit | c47fd8e031a411a66d1c57833c35a3db37cec476 (patch) | |
tree | 6e6e4acb06400663d397c24e89fa4b3ff356e92d /src | |
parent | 9b3c24d15d2336db21d3bbafcaf6268f4e170eef (diff) | |
download | sqlite-c47fd8e031a411a66d1c57833c35a3db37cec476.tar.gz sqlite-c47fd8e031a411a66d1c57833c35a3db37cec476.zip |
Disallow attaching the same database multiple times to the same db connection
in shared cache mode, since doing so leads to deadlock. (CVS 6578)
FossilOrigin-Name: 715f14f1dcaf604d4794bf3e18e245d4f8c5d5a9
Diffstat (limited to 'src')
-rw-r--r-- | src/attach.c | 10 | ||||
-rw-r--r-- | src/btree.c | 19 |
2 files changed, 25 insertions, 4 deletions
diff --git a/src/attach.c b/src/attach.c index d5495361b..d0f81766b 100644 --- a/src/attach.c +++ b/src/attach.c @@ -11,7 +11,7 @@ ************************************************************************* ** This file contains code used to implement the ATTACH and DETACH commands. ** -** $Id: attach.c,v 1.87 2009/04/30 05:40:34 drh Exp $ +** $Id: attach.c,v 1.88 2009/04/30 13:30:33 drh Exp $ */ #include "sqliteInt.h" @@ -119,7 +119,7 @@ static void attachFunc( if( aNew==0 ) return; } db->aDb = aNew; - aNew = &db->aDb[db->nDb++]; + aNew = &db->aDb[db->nDb]; memset(aNew, 0, sizeof(*aNew)); /* Open the database file. If the btree is successfully opened, use @@ -129,7 +129,11 @@ static void attachFunc( rc = sqlite3BtreeFactory(db, zFile, 0, SQLITE_DEFAULT_CACHE_SIZE, db->openFlags | SQLITE_OPEN_MAIN_DB, &aNew->pBt); - if( rc==SQLITE_OK ){ + db->nDb++; + if( rc==SQLITE_CONSTRAINT ){ + rc = SQLITE_ERROR; + zErrDyn = sqlite3MPrintf(db, "database is already attached"); + }else if( rc==SQLITE_OK ){ Pager *pPager; aNew->pSchema = sqlite3SchemaGet(db, aNew->pBt); if( !aNew->pSchema ){ diff --git a/src/btree.c b/src/btree.c index 315991eb5..acc4aaadd 100644 --- a/src/btree.c +++ b/src/btree.c @@ -9,7 +9,7 @@ ** May you share freely, never taking more than you give. ** ************************************************************************* -** $Id: btree.c,v 1.601 2009/04/30 09:10:38 danielk1977 Exp $ +** $Id: btree.c,v 1.602 2009/04/30 13:30:33 drh Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** See the header comment on "btreeInt.h" for additional information. @@ -1401,6 +1401,12 @@ static int btreeInvokeBusyHandler(void *pArg){ ** database file will be deleted when sqlite3BtreeClose() is called. ** If zFilename is ":memory:" then an in-memory database is created ** that is automatically destroyed when it is closed. +** +** If the database is already opened in the same database connection +** and we are in shared cache mode, then the open will fail with an +** SQLITE_CONSTRAINT error. We cannot allow two or more BtShared +** objects in the same database connection since doing so will lead +** to problems with locking. */ int sqlite3BtreeOpen( const char *zFilename, /* Name of the file containing the BTree database */ @@ -1466,6 +1472,17 @@ int sqlite3BtreeOpen( assert( pBt->nRef>0 ); if( 0==strcmp(zFullPathname, sqlite3PagerFilename(pBt->pPager)) && sqlite3PagerVfs(pBt->pPager)==pVfs ){ + int iDb; + for(iDb=db->nDb-1; iDb>=0; iDb--){ + Btree *pExisting = db->aDb[iDb].pBt; + if( pExisting && pExisting->pBt==pBt ){ + sqlite3_mutex_leave(mutexShared); + sqlite3_mutex_leave(mutexOpen); + sqlite3_free(zFullPathname); + sqlite3_free(p); + return SQLITE_CONSTRAINT; + } + } p->pBt = pBt; pBt->nRef++; break; |