1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-11-12 13:01:09 +03:00

Modifications to the way blocking locks are used in SQLITE_ENABLE_SETLK_TIMEOUT builds so that multiple processes or threads may not deadlock when operating on a single database.

FossilOrigin-Name: c516027d5fd876b7d0bf566435667d554db29ded30ad6fc1165caa4a93d015a0
This commit is contained in:
dan
2020-03-27 17:23:17 +00:00
parent 95b395901a
commit 97ccc1bd11
6 changed files with 79 additions and 18 deletions

View File

@@ -3995,7 +3995,9 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){
}
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
case SQLITE_FCNTL_LOCK_TIMEOUT: {
int iOld = pFile->iBusyTimeout;
pFile->iBusyTimeout = *(int*)pArg;
*(int*)pArg = iOld;
return SQLITE_OK;
}
#endif
@@ -4817,6 +4819,24 @@ static int unixShmLock(
assert( pShmNode->hShm>=0 || pDbFd->pInode->bProcessLock==1 );
assert( pShmNode->hShm<0 || pDbFd->pInode->bProcessLock==0 );
/* Check that, if this to be a blocking lock, that locks have been
** obtained in the following order.
**
** 1. Checkpointer lock (ofst==1).
** 2. Recover lock (ofst==2).
** 3. Read locks (ofst>=3 && ofst<SQLITE_SHM_NLOCK).
** 4. Write lock (ofst==0).
**
** In other words, if this is a blocking lock, none of the locks that
** occur later in the above list than the lock being obtained may be
** held. */
#ifdef SQLITE_ENABLE_SETLK_TIMEOUT
assert( pDbFd->iBusyTimeout==0
|| (flags & SQLITE_SHM_UNLOCK) || ofst==0
|| ((p->exclMask|p->sharedMask)&~((1<<ofst)-2))==0
);
#endif
mask = (1<<(ofst+n)) - (1<<ofst);
assert( n>1 || mask==(1<<ofst) );
sqlite3_mutex_enter(pShmNode->pShmMutex);