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:
parent
94929646f1
commit
bbf76eec34
19
manifest
19
manifest
@ -1,5 +1,5 @@
|
||||
C Fix\san\sincrblob2\stest\scase\sso\sthat\sit\sworks\son\s32-bit\ssystems.
|
||||
D 2015-03-10T15:34:47.080
|
||||
C Arrange\sfor\ssome\sof\sthe\stransient\slocks\sin\sWAL\smode\sto\sblock,\sas\sa\ssingle\nto\sthe\sOS\sto\sfix\spriority\sinversions.
|
||||
D 2015-03-10T20:22:35.302
|
||||
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
|
||||
F Makefile.in 2f643d6968dfc0b82d2e546a0525a39079f9e928
|
||||
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
|
||||
@ -214,7 +214,7 @@ F src/os.c 8fd25588eeba74068d41102d26810e216999b6c8
|
||||
F src/os.h 3e57a24e2794a94d3cf2342c6d9a884888cd96bf
|
||||
F src/os_common.h 92815ed65f805560b66166e3583470ff94478f04
|
||||
F src/os_setup.h c9d4553b5aaa6f73391448b265b89bed0b890faa
|
||||
F src/os_unix.c 49d06acee4053920e4a6429844f440b5f975cea4
|
||||
F src/os_unix.c cc903ecc6ebda90ef703d043ddaa7f33de0cab0f
|
||||
F src/os_win.c 8223e7db5b7c4a81d8b161098ac3959400434cdb
|
||||
F src/os_win.h eb7a47aa17b26b77eb97e4823f20a00b8bda12ca
|
||||
F src/pager.c 4120a49ecd37697e28f5ed807f470b9c0b88410c
|
||||
@ -232,7 +232,7 @@ F src/resolve.c f4d79e31ffa5820c2e3d1740baa5e9b190425f2b
|
||||
F src/rowset.c eccf6af6d620aaa4579bd3b72c1b6395d9e9fa1e
|
||||
F src/select.c 94e016b6733b1d39a2f4c8d431155b4c2897d907
|
||||
F src/shell.c cce82ca26392578a4a1ee927dfe55ea3411c7c92
|
||||
F src/sqlite.h.in 356e69db9500b3fd11705c21ca247e19b95884a3
|
||||
F src/sqlite.h.in 4eb59d93caec4b60eada51d3211087746187edef
|
||||
F src/sqlite3.rc 992c9f5fb8285ae285d6be28240a7e8d3a7f2bad
|
||||
F src/sqlite3ext.h 17d487c3c91b0b8c584a32fbeb393f6f795eea7d
|
||||
F src/sqliteInt.h fae682c2b4dfbe489b134d74521c41c088f16ab1
|
||||
@ -304,7 +304,7 @@ F src/vdbesort.c 6d64c5448b64851b99931ede980addc3af70d5e2
|
||||
F src/vdbetrace.c 7e4222955e07dd707a2f360c0eb73452be1cb010
|
||||
F src/vtab.c 699f2b8d509cfe379c33dde33827875d5b030e01
|
||||
F src/vxworks.h c18586c8edc1bddbc15c004fa16aeb1e1342b4fb
|
||||
F src/wal.c 39303f2c9db02a4e422cd8eb2c8760420c6a51fe
|
||||
F src/wal.c 878c8e1a51cb2ec45c395d26b7d5cd9e1a098e4a
|
||||
F src/wal.h df01efe09c5cb8c8e391ff1715cca294f89668a4
|
||||
F src/walker.c c253b95b4ee44b21c406e2a1052636c31ea27804
|
||||
F src/where.c eb141b075776e9864d38f279333e2472a8653202
|
||||
@ -1241,7 +1241,10 @@ F tool/vdbe_profile.tcl 67746953071a9f8f2f668b73fe899074e2c6d8c1
|
||||
F tool/warnings-clang.sh f6aa929dc20ef1f856af04a730772f59283631d4
|
||||
F tool/warnings.sh 0abfd78ceb09b7f7c27c688c8e3fe93268a13b32
|
||||
F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f
|
||||
P fbae6bafd74d8da9c72be5f562a62f80b01cc846
|
||||
R f19e7f30be378d3111028d8dd74f6a7d
|
||||
P 8d0b11c96e15556dd65ced05708a832aef134e69
|
||||
R e3a6235cb886b3e146e5aa9fea4e9436
|
||||
T *branch * wal-blocking-lock
|
||||
T *sym-wal-blocking-lock *
|
||||
T -sym-trunk *
|
||||
U drh
|
||||
Z 0ddafeebdf23c7d95a3d79f2f7b9a23f
|
||||
Z 53b7d268fee9eb6c03e124e757f212c1
|
||||
|
@ -1 +1 @@
|
||||
8d0b11c96e15556dd65ced05708a832aef134e69
|
||||
c6e6d5f4e06c3ac0bfb620c0c728fbc7230c4a02
|
@ -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 ){
|
||||
|
@ -945,6 +945,13 @@ struct sqlite3_io_methods {
|
||||
** pointed to by the pArg argument. This capability is used during testing
|
||||
** and only needs to be supported when SQLITE_TEST is defined.
|
||||
**
|
||||
** <li>[[SQLITE_FCNTL_WAL_BLOCK]]
|
||||
** The [SQLITE_FCNTL_WAL_BLOCK] is a single to the VFS layer that it might
|
||||
** be advantageous to block on the next WAL lock if the lock is not immediately
|
||||
** available. The WAL subsystem issues this ioctl() during some rare
|
||||
** circumstances in order to fix a problem with priority inversion.
|
||||
** Applications should <em>not</em> use this file-control.
|
||||
**
|
||||
** </ul>
|
||||
*/
|
||||
#define SQLITE_FCNTL_LOCKSTATE 1
|
||||
@ -969,6 +976,7 @@ struct sqlite3_io_methods {
|
||||
#define SQLITE_FCNTL_SYNC 21
|
||||
#define SQLITE_FCNTL_COMMIT_PHASETWO 22
|
||||
#define SQLITE_FCNTL_WIN32_SET_HANDLE 23
|
||||
#define SQLITE_FCNTL_WAL_BLOCK 24
|
||||
|
||||
/* deprecated names */
|
||||
#define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE
|
||||
|
17
src/wal.c
17
src/wal.c
@ -788,9 +788,10 @@ static void walUnlockShared(Wal *pWal, int lockIdx){
|
||||
SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED);
|
||||
WALTRACE(("WAL%p: release SHARED-%s\n", pWal, walLockName(lockIdx)));
|
||||
}
|
||||
static int walLockExclusive(Wal *pWal, int lockIdx, int n){
|
||||
static int walLockExclusive(Wal *pWal, int lockIdx, int n, int fBlock){
|
||||
int rc;
|
||||
if( pWal->exclusiveMode ) return SQLITE_OK;
|
||||
if( fBlock ) sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_WAL_BLOCK, 0);
|
||||
rc = sqlite3OsShmLock(pWal->pDbFd, lockIdx, n,
|
||||
SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE);
|
||||
WALTRACE(("WAL%p: acquire EXCLUSIVE-%s cnt=%d %s\n", pWal,
|
||||
@ -1076,7 +1077,7 @@ static int walIndexRecover(Wal *pWal){
|
||||
assert( pWal->writeLock );
|
||||
iLock = WAL_ALL_BUT_WRITE + pWal->ckptLock;
|
||||
nLock = SQLITE_SHM_NLOCK - iLock;
|
||||
rc = walLockExclusive(pWal, iLock, nLock);
|
||||
rc = walLockExclusive(pWal, iLock, nLock, 0);
|
||||
if( rc ){
|
||||
return rc;
|
||||
}
|
||||
@ -1610,7 +1611,7 @@ static int walBusyLock(
|
||||
){
|
||||
int rc;
|
||||
do {
|
||||
rc = walLockExclusive(pWal, lockIdx, n);
|
||||
rc = walLockExclusive(pWal, lockIdx, n, 0);
|
||||
}while( xBusy && rc==SQLITE_BUSY && xBusy(pBusyArg) );
|
||||
return rc;
|
||||
}
|
||||
@ -2043,7 +2044,7 @@ static int walIndexReadHdr(Wal *pWal, int *pChanged){
|
||||
walUnlockShared(pWal, WAL_WRITE_LOCK);
|
||||
rc = SQLITE_READONLY_RECOVERY;
|
||||
}
|
||||
}else if( SQLITE_OK==(rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1)) ){
|
||||
}else if( SQLITE_OK==(rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1, 1)) ){
|
||||
pWal->writeLock = 1;
|
||||
if( SQLITE_OK==(rc = walIndexPage(pWal, 0, &page0)) ){
|
||||
badHdr = walIndexTryHdr(pWal, pChanged);
|
||||
@ -2249,7 +2250,7 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){
|
||||
&& (mxReadMark<pWal->hdr.mxFrame || mxI==0)
|
||||
){
|
||||
for(i=1; i<WAL_NREADER; i++){
|
||||
rc = walLockExclusive(pWal, WAL_READ_LOCK(i), 1);
|
||||
rc = walLockExclusive(pWal, WAL_READ_LOCK(i), 1, 0);
|
||||
if( rc==SQLITE_OK ){
|
||||
mxReadMark = pInfo->aReadMark[i] = pWal->hdr.mxFrame;
|
||||
mxI = i;
|
||||
@ -2505,7 +2506,7 @@ int sqlite3WalBeginWriteTransaction(Wal *pWal){
|
||||
/* Only one writer allowed at a time. Get the write lock. Return
|
||||
** SQLITE_BUSY if unable.
|
||||
*/
|
||||
rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1);
|
||||
rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1, 0);
|
||||
if( rc ){
|
||||
return rc;
|
||||
}
|
||||
@ -2650,7 +2651,7 @@ static int walRestartLog(Wal *pWal){
|
||||
if( pInfo->nBackfill>0 ){
|
||||
u32 salt1;
|
||||
sqlite3_randomness(4, &salt1);
|
||||
rc = walLockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1);
|
||||
rc = walLockExclusive(pWal, WAL_READ_LOCK(1), WAL_NREADER-1, 0);
|
||||
if( rc==SQLITE_OK ){
|
||||
/* If all readers are using WAL_READ_LOCK(0) (in other words if no
|
||||
** readers are currently using the WAL), then the transactions
|
||||
@ -2975,7 +2976,7 @@ int sqlite3WalCheckpoint(
|
||||
|
||||
/* IMPLEMENTATION-OF: R-62028-47212 All calls obtain an exclusive
|
||||
** "checkpoint" lock on the database file. */
|
||||
rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1);
|
||||
rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1, 0);
|
||||
if( rc ){
|
||||
/* EVIDENCE-OF: R-10421-19736 If any other process is running a
|
||||
** checkpoint operation at the same time, the lock cannot be obtained and
|
||||
|
Loading…
Reference in New Issue
Block a user