aboutsummaryrefslogtreecommitdiff
path: root/src/memdb.c
diff options
context:
space:
mode:
authordan <Dan Kennedy>2022-12-19 14:06:36 +0000
committerdan <Dan Kennedy>2022-12-19 14:06:36 +0000
commit1532f9d1552a6f827538fe3ebc26ecb267c5e205 (patch)
tree72ea4826043eae1dc9b0501814b354a0bc236706 /src/memdb.c
parenta4569bd5d0913bfa1e3c8ce9dc6ca395e434d299 (diff)
downloadsqlite-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.c117
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