aboutsummaryrefslogtreecommitdiff
path: root/src/os_unix.c
diff options
context:
space:
mode:
authordan <dan@noemail.net>2020-08-28 20:01:06 +0000
committerdan <dan@noemail.net>2020-08-28 20:01:06 +0000
commit6acdee676551f5fc2fc5ab89bed8c379769eafa9 (patch)
treeefab63460212d2775630d494f69ab4ea72e2da23 /src/os_unix.c
parent8337da6678bc2f83c0ba84aec89c751cdeadf1e5 (diff)
downloadsqlite-6acdee676551f5fc2fc5ab89bed8c379769eafa9.tar.gz
sqlite-6acdee676551f5fc2fc5ab89bed8c379769eafa9.zip
Fix handling of an xShmLock(SHARED, UNLOCK) call when the caller does not hold any lock on the specified slot, but another connection in the same process holds an EXCLUSIVE.
FossilOrigin-Name: 3eb365027b885e1f61965efd53a3643b6ff441ae01e79038a091314516a50dd4
Diffstat (limited to 'src/os_unix.c')
-rw-r--r--src/os_unix.c40
1 files changed, 21 insertions, 19 deletions
diff --git a/src/os_unix.c b/src/os_unix.c
index 0eb2d5b00..5419a042a 100644
--- a/src/os_unix.c
+++ b/src/os_unix.c
@@ -4888,30 +4888,32 @@ static int unixShmLock(
sqlite3_mutex_enter(pShmNode->pShmMutex);
assert( assertLockingArrayOk(pShmNode) );
if( flags & SQLITE_SHM_UNLOCK ){
- int ii;
- int bUnlock = 1;
+ if( (p->exclMask|p->sharedMask) & mask ){
+ int ii;
+ int bUnlock = 1;
- for(ii=ofst; ii<ofst+n; ii++){
- if( aLock[ii]>((p->sharedMask & (1<<ii)) ? 1 : 0) ){
- bUnlock = 0;
+ for(ii=ofst; ii<ofst+n; ii++){
+ if( aLock[ii]>((p->sharedMask & (1<<ii)) ? 1 : 0) ){
+ bUnlock = 0;
+ }
}
- }
- if( bUnlock ){
- rc = unixShmSystemLock(pDbFd, F_UNLCK, ofst+UNIX_SHM_BASE, n);
- if( rc==SQLITE_OK ){
- memset(&aLock[ofst], 0, sizeof(int)*n);
+ if( bUnlock ){
+ rc = unixShmSystemLock(pDbFd, F_UNLCK, ofst+UNIX_SHM_BASE, n);
+ if( rc==SQLITE_OK ){
+ memset(&aLock[ofst], 0, sizeof(int)*n);
+ }
+ }else if( p->sharedMask & (1<<ofst) ){
+ assert( n==1 && aLock[ofst]>1 );
+ aLock[ofst]--;
}
- }else if( p->sharedMask & (1<<ofst) ){
- assert( n==1 && aLock[ofst]>1 );
- aLock[ofst]--;
- }
- /* Undo the local locks */
- if( rc==SQLITE_OK ){
- p->exclMask &= ~mask;
- p->sharedMask &= ~mask;
- }
+ /* Undo the local locks */
+ if( rc==SQLITE_OK ){
+ p->exclMask &= ~mask;
+ p->sharedMask &= ~mask;
+ }
+ }
}else if( flags & SQLITE_SHM_SHARED ){
assert( n==1 );
assert( (p->exclMask & (1<<ofst))==0 );