diff options
author | dan <dan@noemail.net> | 2020-08-28 20:01:06 +0000 |
---|---|---|
committer | dan <dan@noemail.net> | 2020-08-28 20:01:06 +0000 |
commit | 6acdee676551f5fc2fc5ab89bed8c379769eafa9 (patch) | |
tree | efab63460212d2775630d494f69ab4ea72e2da23 /src/os_unix.c | |
parent | 8337da6678bc2f83c0ba84aec89c751cdeadf1e5 (diff) | |
download | sqlite-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.c | 40 |
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 ); |