aboutsummaryrefslogtreecommitdiff
path: root/src/memdb.c
diff options
context:
space:
mode:
authordrh <>2022-12-07 16:58:04 +0000
committerdrh <>2022-12-07 16:58:04 +0000
commit7c66faa634be0e89553e0a985270788751f82238 (patch)
treecbd2fd476b739ab1e49a08a230b7169bef3623ea /src/memdb.c
parentb54f71e205c578303fa50cfb11a985e9b73ca3b0 (diff)
downloadsqlite-7c66faa634be0e89553e0a985270788751f82238.tar.gz
sqlite-7c66faa634be0e89553e0a985270788751f82238.zip
Streamline and improve testing of the locking in the memdb VFS.
Follow-on to [15f0be8a640e7bfa]. FossilOrigin-Name: d71a08375aeb525c10037c373b8eeb7e29f7dfaf7c4bfc02f4d99616c5940405
Diffstat (limited to 'src/memdb.c')
-rw-r--r--src/memdb.c28
1 files changed, 20 insertions, 8 deletions
diff --git a/src/memdb.c b/src/memdb.c
index 7485f51ff..4ea3cffde 100644
--- a/src/memdb.c
+++ b/src/memdb.c
@@ -370,21 +370,33 @@ static int memdbLock(sqlite3_file *pFile, int eLock){
int rc = 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 ){
- /* Taking an EXCLUSIVE lock. Fail if we only have SHARED and any
- ** other client has any kind of write-lock. Also fail if any other
- ** client is holding read-lock. */
- if( pThis->eLock<=SQLITE_LOCK_SHARED && p->nWrLock ){
- rc = SQLITE_BUSY;
- }else if( p->nRdLock>1 ){
+ /* 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;
}
- p->nWrLock = 1;
- }else if( pThis->eLock<=SQLITE_LOCK_SHARED ){
+ }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 ){