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/btree.c | |
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/btree.c')
-rw-r--r-- | src/btree.c | 19 |
1 files changed, 18 insertions, 1 deletions
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; |