mirror of
https://github.com/sqlite/sqlite.git
synced 2025-11-12 13:01:09 +03:00
Arrange for some of the transient locks in WAL mode to block, as a single
to the OS to fix priority inversions. FossilOrigin-Name: c6e6d5f4e06c3ac0bfb620c0c728fbc7230c4a02
This commit is contained in:
@@ -248,6 +248,7 @@ static pid_t randomnessPid = 0;
|
||||
#define UNIXFILE_URI 0x40 /* Filename might have query parameters */
|
||||
#define UNIXFILE_NOLOCK 0x80 /* Do no file locking */
|
||||
#define UNIXFILE_WARNED 0x0100 /* verifyDbFile() warnings issued */
|
||||
#define UNIXFILE_BLOCK 0x0200 /* Next SHM lock might block */
|
||||
|
||||
/*
|
||||
** Include code that is common to all os_*.c files
|
||||
@@ -4090,15 +4091,17 @@ struct unixShm {
|
||||
** otherwise.
|
||||
*/
|
||||
static int unixShmSystemLock(
|
||||
unixShmNode *pShmNode, /* Apply locks to this open shared-memory segment */
|
||||
unixFile *pFile, /* Open connection to the WAL file */
|
||||
int lockType, /* F_UNLCK, F_RDLCK, or F_WRLCK */
|
||||
int ofst, /* First byte of the locking range */
|
||||
int n /* Number of bytes to lock */
|
||||
){
|
||||
struct flock f; /* The posix advisory locking structure */
|
||||
int rc = SQLITE_OK; /* Result code form fcntl() */
|
||||
unixShmNode *pShmNode; /* Apply locks to this open shared-memory segment */
|
||||
struct flock f; /* The posix advisory locking structure */
|
||||
int rc = SQLITE_OK; /* Result code form fcntl() */
|
||||
|
||||
/* Access to the unixShmNode object is serialized by the caller */
|
||||
pShmNode = pFile->pInode->pShmNode;
|
||||
assert( sqlite3_mutex_held(pShmNode->mutex) || pShmNode->nRef==0 );
|
||||
|
||||
/* Shared locks never span more than one byte */
|
||||
@@ -4108,6 +4111,7 @@ static int unixShmSystemLock(
|
||||
assert( n>=1 && n<SQLITE_SHM_NLOCK );
|
||||
|
||||
if( pShmNode->h>=0 ){
|
||||
int lkType;
|
||||
/* Initialize the locking parameters */
|
||||
memset(&f, 0, sizeof(f));
|
||||
f.l_type = lockType;
|
||||
@@ -4115,8 +4119,10 @@ static int unixShmSystemLock(
|
||||
f.l_start = ofst;
|
||||
f.l_len = n;
|
||||
|
||||
rc = osFcntl(pShmNode->h, F_SETLK, &f);
|
||||
lkType = (pFile->ctrlFlags & UNIXFILE_BLOCK)!=0 ? F_SETLKW : F_SETLK;
|
||||
rc = osFcntl(pShmNode->h, lkType, &f);
|
||||
rc = (rc!=(-1)) ? SQLITE_OK : SQLITE_BUSY;
|
||||
pFile->ctrlFlags &= ~UNIXFILE_BLOCK;
|
||||
}
|
||||
|
||||
/* Update the global lock state and do debug tracing */
|
||||
@@ -4326,13 +4332,13 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
|
||||
** If not, truncate the file to zero length.
|
||||
*/
|
||||
rc = SQLITE_OK;
|
||||
if( unixShmSystemLock(pShmNode, F_WRLCK, UNIX_SHM_DMS, 1)==SQLITE_OK ){
|
||||
if( unixShmSystemLock(pDbFd, F_WRLCK, UNIX_SHM_DMS, 1)==SQLITE_OK ){
|
||||
if( robust_ftruncate(pShmNode->h, 0) ){
|
||||
rc = unixLogError(SQLITE_IOERR_SHMOPEN, "ftruncate", zShmFilename);
|
||||
}
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = unixShmSystemLock(pShmNode, F_RDLCK, UNIX_SHM_DMS, 1);
|
||||
rc = unixShmSystemLock(pDbFd, F_RDLCK, UNIX_SHM_DMS, 1);
|
||||
}
|
||||
if( rc ) goto shm_open_err;
|
||||
}
|
||||
@@ -4564,7 +4570,7 @@ static int unixShmLock(
|
||||
|
||||
/* Unlock the system-level locks */
|
||||
if( (mask & allMask)==0 ){
|
||||
rc = unixShmSystemLock(pShmNode, F_UNLCK, ofst+UNIX_SHM_BASE, n);
|
||||
rc = unixShmSystemLock(pDbFd, F_UNLCK, ofst+UNIX_SHM_BASE, n);
|
||||
}else{
|
||||
rc = SQLITE_OK;
|
||||
}
|
||||
@@ -4592,7 +4598,7 @@ static int unixShmLock(
|
||||
/* Get shared locks at the system level, if necessary */
|
||||
if( rc==SQLITE_OK ){
|
||||
if( (allShared & mask)==0 ){
|
||||
rc = unixShmSystemLock(pShmNode, F_RDLCK, ofst+UNIX_SHM_BASE, n);
|
||||
rc = unixShmSystemLock(pDbFd, F_RDLCK, ofst+UNIX_SHM_BASE, n);
|
||||
}else{
|
||||
rc = SQLITE_OK;
|
||||
}
|
||||
@@ -4617,7 +4623,7 @@ static int unixShmLock(
|
||||
** also mark the local connection as being locked.
|
||||
*/
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = unixShmSystemLock(pShmNode, F_WRLCK, ofst+UNIX_SHM_BASE, n);
|
||||
rc = unixShmSystemLock(pDbFd, F_WRLCK, ofst+UNIX_SHM_BASE, n);
|
||||
if( rc==SQLITE_OK ){
|
||||
assert( (p->sharedMask & mask)==0 );
|
||||
p->exclMask |= mask;
|
||||
@@ -7222,6 +7228,10 @@ static int proxyTransformUnixFile(unixFile *pFile, const char *path) {
|
||||
*/
|
||||
static int proxyFileControl(sqlite3_file *id, int op, void *pArg){
|
||||
switch( op ){
|
||||
case SQLITE_FCNTL_WAL_BLOCK: {
|
||||
id->ctrlFlags |= UNIXFILE_BLOCK;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
case SQLITE_FCNTL_GET_LOCKPROXYFILE: {
|
||||
unixFile *pFile = (unixFile*)id;
|
||||
if( pFile->pMethod == &proxyIoMethods ){
|
||||
|
||||
Reference in New Issue
Block a user