From fd72563d0aaf09857ab37c38ff4ac0d3b5df92e6 Mon Sep 17 00:00:00 2001 From: drh Date: Mon, 26 Mar 2018 20:43:05 +0000 Subject: [PATCH] Avoid a race condition that might cause a busy_timeout to last longer than it should. FossilOrigin-Name: b81960561b47a1b49646f2f8870dd0684dc4ca7c0b9e11076fd713de66b75972 --- manifest | 21 +++++++++------------ manifest.uuid | 2 +- src/btree.c | 1 + src/os_unix.c | 11 ++++------- src/pager.c | 14 ++++++++++++++ src/pager.h | 5 +++++ 6 files changed, 34 insertions(+), 20 deletions(-) diff --git a/manifest b/manifest index 3aa9ebb526..d471353901 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\sinfrastructure\sto\ssupport\sfor\susing\sF_SETLKW\swith\sa\stimeout\son\ssystem\nthat\ssupport\sthat\sfunctionality.\s\sRequires\sSQLITE_ENABLE_SETLK_TIMEOUT. -D 2018-03-26T17:40:53.817 +C Avoid\sa\srace\scondition\sthat\smight\scause\sa\sbusy_timeout\sto\slast\slonger\sthan\nit\sshould. +D 2018-03-26T20:43:05.286 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F Makefile.in 7016fc56c6b9bfe5daac4f34be8be38d8c0b5fab79ccbfb764d3b23bf1c6fff3 @@ -432,7 +432,7 @@ F src/auth.c 6277d63837357549fe14e723490d6dc1a38768d71c795c5eb5c0f8a99f918f73 F src/backup.c faf17e60b43233c214aae6a8179d24503a61e83b F src/bitvec.c 17ea48eff8ba979f1f5b04cc484c7bb2be632f33 F src/btmutex.c 0e9ce2d56159b89b9bc8e197e023ee11e39ff8ca -F src/btree.c 4c30691becf0524c2f490291c93a9bdaf5cfb15cc42cf96737982c5ae14b773f +F src/btree.c 9eb9531c65346bbfccf5325384b7db1849daf4db6601dcfe21ba5c5b20623b64 F src/btree.h 0866c0a08255142ea0e754aabd211c843cab32045c978a592a43152405ed0c84 F src/btreeInt.h 620ab4c7235f43572cf3ac2ac8723cbdf68073be4d29da24897c7b77dda5fd96 F src/build.c 8b53aacc26944bb7fd9ab5ddeedecb4cc7c4b84df3a420cf6d2b8f772ad421df @@ -475,11 +475,11 @@ F src/os.c 22d31db3ca5a96a408fbf1ceeaaebcaf64c87024d2ff9fe1cf2ddbec3e75c104 F src/os.h 48388821692e87da174ea198bf96b1b2d9d83be5dfc908f673ee21fafbe0d432 F src/os_common.h b2f4707a603e36811d9b1a13278bffd757857b85 F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586 -F src/os_unix.c 8aaa2ee9c87f7323d741454dc62d70f93990031d0d937f86b0d4f40d45a9b8d4 +F src/os_unix.c 2b53b0b8ddc580db096252c721729e5f5f2f355b4fc056f8f3fb328aeb3c9e8a F src/os_win.c eb03c6d52f893bcd7fdd4c6006674c13c1b5e49543fec98d605201af2997171c F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a -F src/pager.c 941cba7d6acaf43598c4c33f655d2a2910c3c6c5fd92169269cff964bb8eadda -F src/pager.h 868d177d847238d9c282275465d256a2c2ddccc4ae08a1eb097d8a953d7e4acb +F src/pager.c 8f2611ef1eb92a18e1605cb4ff37dfcc05acc6000eb6c6c263105ef5aba54661 +F src/pager.h c571b064df842ec8f2e90855dead9acf4cbe0d1b2c05afe0ef0d0145f7fd0388 F src/parse.y 140bbc53b5f67f731239f7fc8704a4f1e60cbbc10fb84bf9577322f974725f19 F src/pcache.c 135ef0bc6fb2e3b7178d49ab5c9176254c8a691832c1bceb1156b2fbdd0869bd F src/pcache.h 072f94d29281cffd99e46c1539849f248c4b56ae7684c1f36626797fee375170 @@ -1717,10 +1717,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 6c40c5574f4ae9795a142d01a8f84afd1b72678ea5f6bfca14a8646c4e862605 -R b2318b0232c803ad8fe7d3fa9a19c19e -T *branch * lowlevel-lock-timeout -T *sym-lowlevel-lock-timeout * -T -sym-trunk * +P 2e54a7433ece4eb27e71bda6f2d121d5aa46ddd5a481357d8543d1432aaad689 +R 9a06c4f711bb138e77b576e4f0584ff2 U drh -Z a47300717ce425457190ed008e7aa2a5 +Z cae5f0752336b48b9e35b37383c91a64 diff --git a/manifest.uuid b/manifest.uuid index b8ff59f19f..75412f0912 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -2e54a7433ece4eb27e71bda6f2d121d5aa46ddd5a481357d8543d1432aaad689 \ No newline at end of file +b81960561b47a1b49646f2f8870dd0684dc4ca7c0b9e11076fd713de66b75972 \ No newline at end of file diff --git a/src/btree.c b/src/btree.c index 6bcf379d61..402503916d 100644 --- a/src/btree.c +++ b/src/btree.c @@ -3373,6 +3373,7 @@ int sqlite3BtreeBeginTrans(Btree *p, int wrflag){ } }while( (rc&0xFF)==SQLITE_BUSY && pBt->inTransaction==TRANS_NONE && btreeInvokeBusyHandler(pBt) ); + sqlite3PagerResetLockTimeout(pBt->pPager); if( rc==SQLITE_OK ){ if( p->inTrans==TRANS_NONE ){ diff --git a/src/os_unix.c b/src/os_unix.c index ac4ec2f2f0..2b9c117e30 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -1490,18 +1490,15 @@ static int osSetPosixAdvisoryLock( unixFile *pFile /* Structure holding timeout value */ ){ int rc = osFcntl(h,F_SETLK,pLock); - if( rc<0 && pFile->iBusyTimeout>0 ){ + while( rc<0 && pFile->iBusyTimeout>0 ){ /* On systems that support some kind of blocking file lock with a timeout, ** make appropriate changes here to invoke that blocking file lock. On ** generic posix, however, there is no such API. So we simply try the ** lock once every millisecond until either the timeout expires, or until ** the lock is obtained. */ - do{ - usleep(1000); - rc = osFcntl(h,F_SETLK,pLock); - pFile->iBusyTimeout--; - }while( rc<0 && pFile->iBusyTimeout>0 ); - pFile->iBusyTimeout = 0; + usleep(1000); + rc = osFcntl(h,F_SETLK,pLock); + pFile->iBusyTimeout--; } return rc; } diff --git a/src/pager.c b/src/pager.c index 55f90057ef..85d1845e95 100644 --- a/src/pager.c +++ b/src/pager.c @@ -5693,6 +5693,7 @@ void sqlite3PagerUnrefPageOne(DbPage *pPg){ assert( pPg->pgno==1 ); assert( (pPg->flags & PGHDR_MMAP)==0 ); /* Page1 is never memory mapped */ pPager = pPg->pPager; + sqlite3PagerResetLockTimeout(pPager); sqlite3PcacheRelease(pPg); pagerUnlockIfUnused(pPager); } @@ -6970,6 +6971,18 @@ sqlite3_file *sqlite3PagerFile(Pager *pPager){ return pPager->fd; } +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT +/* +** Reset the lock timeout for pager. +*/ +void sqlite3PagerResetLockTimeout(Pager *pPager){ + if( isOpen(pPager->fd) ){ + int x = 0; + sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_LOCK_TIMEOUT, &x); + } +} +#endif + /* ** Return the file handle for the journal file (if it exists). ** This will be either the rollback journal or the WAL file. @@ -7430,6 +7443,7 @@ int sqlite3PagerCheckpoint( pPager->walSyncFlags, pPager->pageSize, (u8 *)pPager->pTmpSpace, pnLog, pnCkpt ); + sqlite3PagerResetLockTimeout(pPager); } return rc; } diff --git a/src/pager.h b/src/pager.h index 48bc80df1d..730e366fbb 100644 --- a/src/pager.h +++ b/src/pager.h @@ -212,6 +212,11 @@ int sqlite3PagerIsMemdb(Pager*); void sqlite3PagerCacheStat(Pager *, int, int, int *); void sqlite3PagerClearCache(Pager*); int sqlite3SectorSize(sqlite3_file *); +#ifdef SQLITE_ENABLE_SETLK_TIMEOUT +void sqlite3PagerResetLockTimeout(Pager *pPager); +#else +# define sqlite3PagerResetLockTimeout(X) +#endif /* Functions used to truncate the database file. */ void sqlite3PagerTruncateImage(Pager*,Pgno);