diff options
author | dan <Dan Kennedy> | 2022-12-19 14:06:36 +0000 |
---|---|---|
committer | dan <Dan Kennedy> | 2022-12-19 14:06:36 +0000 |
commit | 1532f9d1552a6f827538fe3ebc26ecb267c5e205 (patch) | |
tree | 72ea4826043eae1dc9b0501814b354a0bc236706 /src/memdb.c | |
parent | a4569bd5d0913bfa1e3c8ce9dc6ca395e434d299 (diff) | |
download | sqlite-1532f9d1552a6f827538fe3ebc26ecb267c5e205.tar.gz sqlite-1532f9d1552a6f827538fe3ebc26ecb267c5e205.zip |
Fix an assert() in fts5. Simplify memdb xLock/xUnlock some.
FossilOrigin-Name: 7fe158aa8071acadd959b2b4a4b66e8a7f7eecec207ba681abf516b0457c2921
Diffstat (limited to 'src/memdb.c')
-rw-r--r-- | src/memdb.c | 117 |
1 files changed, 68 insertions, 49 deletions
diff --git a/src/memdb.c b/src/memdb.c index 97b6bed0f..e9e5eff7f 100644 --- a/src/memdb.c +++ b/src/memdb.c @@ -109,6 +109,7 @@ static int memdbTruncate(sqlite3_file*, sqlite3_int64 size); static int memdbSync(sqlite3_file*, int flags); static int memdbFileSize(sqlite3_file*, sqlite3_int64 *pSize); static int memdbLock(sqlite3_file*, int); +static int memdbUnlock(sqlite3_file*, int); /* static int memdbCheckReservedLock(sqlite3_file*, int *pResOut);// not used */ static int memdbFileControl(sqlite3_file*, int op, void *pArg); /* static int memdbSectorSize(sqlite3_file*); // not used */ @@ -167,7 +168,7 @@ static const sqlite3_io_methods memdb_io_methods = { memdbSync, /* xSync */ memdbFileSize, /* xFileSize */ memdbLock, /* xLock */ - memdbLock, /* xUnlock - same as xLock in this case */ + memdbUnlock, /* xUnlock */ 0, /* memdbCheckReservedLock, */ /* xCheckReservedLock */ memdbFileControl, /* xFileControl */ 0, /* memdbSectorSize,*/ /* xSectorSize */ @@ -368,64 +369,82 @@ static int memdbLock(sqlite3_file *pFile, int eLock){ MemFile *pThis = (MemFile*)pFile; MemStore *p = pThis->pStore; int rc = SQLITE_OK; - if( eLock==pThis->eLock ) return SQLITE_OK; + if( eLock<=pThis->eLock ) return SQLITE_OK; memdbEnter(p); - assert( p->nWrLock==0 || p->nWrLock==1 ); /* No more than 1 write lock */ - if( eLock>SQLITE_LOCK_SHARED ){ - assert( pThis->eLock>=SQLITE_LOCK_SHARED ); - if( p->mFlags & SQLITE_DESERIALIZE_READONLY ){ - rc = SQLITE_READONLY; - }else if( eLock==SQLITE_LOCK_EXCLUSIVE ){ - /* We never go for an EXCLUSIVE lock unless we already hold SHARED or - ** higher */ - assert( pThis->eLock>=SQLITE_LOCK_SHARED ); - testcase( pThis->eLock==SQLITE_LOCK_SHARED ); - - /* Because we are holding SHARED or more, there must be at least - ** one read lock */ - assert( p->nRdLock>0 ); - - /* The only way that there can be an existing write lock is if we - ** currently hold it. Otherwise, we would have never been able to - ** promote from NONE to SHARED. */ - assert( p->nWrLock==0 || pThis->eLock>SQLITE_LOCK_SHARED ); - - if( p->nRdLock>1 ){ - /* Cannot take EXCLUSIVE if somebody else is holding SHARED */ - rc = SQLITE_BUSY; - }else{ - p->nWrLock = 1; + + assert( p->nWrLock==0 || p->nWrLock==1 ); + assert( pThis->eLock<=SQLITE_LOCK_SHARED || p->nWrLock==1 ); + assert( pThis->eLock==SQLITE_LOCK_NONE || p->nRdLock>=1 ); + + if( eLock>SQLITE_LOCK_SHARED && (p->mFlags & SQLITE_DESERIALIZE_READONLY) ){ + rc = SQLITE_READONLY; + }else{ + switch( eLock ){ + case SQLITE_LOCK_SHARED: { + assert( pThis->eLock==SQLITE_LOCK_NONE ); + if( p->nWrLock>0 ){ + rc = SQLITE_BUSY; + }else{ + p->nRdLock++; + } + break; + }; + + case SQLITE_LOCK_RESERVED: + case SQLITE_LOCK_PENDING: { + assert( pThis->eLock>=SQLITE_LOCK_SHARED ); + if( pThis->eLock==SQLITE_LOCK_SHARED ){ + if( p->nWrLock>0 ){ + rc = SQLITE_BUSY; + }else{ + p->nWrLock = 1; + } + } + break; } - }else if( ALWAYS(pThis->eLock<=SQLITE_LOCK_SHARED) ){ - /* Upgrading to RESERVED or PENDING from SHARED. Fail if any other - ** client has a write-lock of any kind. */ - if( p->nWrLock ){ - rc = SQLITE_BUSY; - }else{ - p->nWrLock = 1; + + default: { + assert( eLock==SQLITE_LOCK_EXCLUSIVE ); + assert( pThis->eLock>=SQLITE_LOCK_SHARED ); + if( p->nRdLock>1 ){ + rc = SQLITE_BUSY; + }else if( pThis->eLock==SQLITE_LOCK_SHARED ){ + p->nWrLock = 1; + } + break; } } - }else if( eLock==SQLITE_LOCK_SHARED ){ - if( pThis->eLock > SQLITE_LOCK_SHARED ){ - assert( p->nWrLock==1 ); - p->nWrLock = 0; - }else if( p->nWrLock ){ - rc = SQLITE_BUSY; - }else{ - p->nRdLock++; + } + if( rc==SQLITE_OK ) pThis->eLock = eLock; + memdbLeave(p); + return rc; +} + +/* +** Unlock an memdb-file. +*/ +static int memdbUnlock(sqlite3_file *pFile, int eLock){ + MemFile *pThis = (MemFile*)pFile; + MemStore *p = pThis->pStore; + int rc = SQLITE_OK; + if( eLock>=pThis->eLock ) return SQLITE_OK; + memdbEnter(p); + + assert( eLock==SQLITE_LOCK_SHARED || eLock==SQLITE_LOCK_NONE ); + if( eLock==SQLITE_LOCK_SHARED ){ + if( pThis->eLock>SQLITE_LOCK_SHARED ){ + p->nWrLock--; } }else{ - assert( eLock==SQLITE_LOCK_NONE ); - if( pThis->eLock>SQLITE_LOCK_SHARED ){ - assert( p->nWrLock==1 ); - p->nWrLock = 0; + if( pThis->eLock>SQLITE_LOCK_SHARED ){ + p->nWrLock--; } - assert( p->nRdLock>0 ); p->nRdLock--; } - if( rc==SQLITE_OK ) pThis->eLock = eLock; + + pThis->eLock = eLock; memdbLeave(p); - return rc; + return SQLITE_OK; } #if 0 |