]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Use a blocking call to obtain the wal-mode WRITER lock in some cases.
authordan <dan@noemail.net>
Wed, 10 May 2017 13:46:29 +0000 (13:46 +0000)
committerdan <dan@noemail.net>
Wed, 10 May 2017 13:46:29 +0000 (13:46 +0000)
FossilOrigin-Name: 4464ca1d686b5c457995cc885d4a8704e402ad387aa4cc37de199276b28cc08e

manifest
manifest.uuid
src/pager.c
src/server.c
src/wal.c

index 020c032e64d4ac92d89cbe65a3a35b2837d763e3..4cacc9c1f54cd88697975c5e0fd6d9a18fded720 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\sa\sproblem\swith\swrapping\sthe\slog\sfile\sin\sserver\smode.
-D 2017-05-09T16:32:19.219
+C Use\sa\sblocking\scall\sto\sobtain\sthe\swal-mode\sWRITER\slock\sin\ssome\scases.
+D 2017-05-10T13:46:29.059
 F Makefile.in 1cc758ce3374a32425e4d130c2fe7b026b20de5b8843243de75f087c0a2661fb
 F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
 F Makefile.msc 6a8c838220f7c00820e1fc0ac1bccaaa8e5676067e1dbfa1bafa7a4ffecf8ae6
@@ -389,7 +389,7 @@ F src/os_setup.h 0dbaea40a7d36bf311613d31342e0b99e2536586
 F src/os_unix.c 30e2c43e4955db990e5b5a81e901f8aa74cc8820
 F src/os_win.c 2a6c73eef01c51a048cc4ddccd57f981afbec18a
 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a
-F src/pager.c aec4a28d8aace83424bc9ec1f85867f2defd0e2173caba11628ff5daee2c4d5c
+F src/pager.c 5326f380451332c254690c577c56a668e18207fb505014d2238bb43cca941148
 F src/pager.h ea05992c581c3366279fb1d436944604b4be17208ebb41fa407306e5e4b34205
 F src/parse.y 0513387ce02fea97897d8caef82d45f347818593f24f1bdc48e0c530a8af122d
 F src/pcache.c 62835bed959e2914edd26afadfecce29ece0e870
@@ -403,7 +403,7 @@ F src/random.c 80f5d666f23feb3e6665a6ce04c7197212a88384
 F src/resolve.c 3e518b962d932a997fae373366880fc028c75706
 F src/rowset.c 7b7e7e479212e65b723bf40128c7b36dc5afdfac
 F src/select.c 4f0adefaa5e9417459b07757e0f6060cac97930a86f0fba9797bab233ced66c0
-F src/server.c ffeab1087cdae36f1454065b1feb49c61ce48db0088c6130e28197d6bfbc7545
+F src/server.c 0dc1e45a211636dacc1dff6f8c94e2fcb8a171258797638ef8b8afa803190b66
 F src/shell.c e5950029da103c5d378e71d548759459b9a7fc76177a71562c22082c705745ab
 F src/sqlite.h.in 8d126e4cfbd1f4bc6f4043aacd77f78b45613e7d630185d49a5d099394247483
 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8
@@ -481,7 +481,7 @@ F src/vdbesort.c e72fe02a2121386ba767ede8942e9450878b8fc873abf3d1b6824485f092570
 F src/vdbetrace.c 41963d5376f0349842b5fc4aaaaacd7d9cdc0834
 F src/vtab.c 35b9bdc2b41de32a417141d12097bcc4e29a77ed7cdb8f836d1d2305d946b61b
 F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9
-F src/wal.c 85d564ebecc9c6642b256df77859559606c3009afc78b8cb9a85aa7851af7cf3
+F src/wal.c 8db0fb216f08c20da136b521dc294ae28c7ae6658c37460c97ba661735d186f5
 F src/wal.h 739d92494eb18b6d8f3e353e66c10eb8f94534bafd336ece9f3f60235317ea08
 F src/walker.c b71a992b413b3a022572eccf29ef4b4890223791
 F src/where.c c6352f15be5031907c68bcbde96cad1a6da20e9f4051d10168a59235de9a8566
@@ -1583,7 +1583,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 b733afc1d0abc09861903ce8e27a8f2462ec871967f5d3dc2847b31bb28b55f3
-R a0c4295002e104ba7ee36216fd337c0e
+P 270b7d1eacb57827465946262b31c5c890d7fc5b5618ccd9e220bc2f9546de54
+R 093b295a1ab0adce73d443998b14bdc9
 U dan
-Z 37eef1e78eb4ad8d709fcbedf553cadf
+Z 579dd9e65d85708090977566fef93a28
index cc0faeb40ebb241f9884820b986e15cb06784ede..b93192d744f687a6ef67e3d332a03fa660580e0b 100644 (file)
@@ -1 +1 @@
-270b7d1eacb57827465946262b31c5c890d7fc5b5618ccd9e220bc2f9546de54
\ No newline at end of file
+4464ca1d686b5c457995cc885d4a8704e402ad387aa4cc37de199276b28cc08e
\ No newline at end of file
index e0a4a47313a712ca3ca907f69808aef17209f439..c25173a677417f11cc92245a3403c1368d66e25a 100644 (file)
@@ -5688,7 +5688,7 @@ int sqlite3PagerGet(
 ){
 #ifdef SQLITE_SERVER_EDITION
   if( pagerIsServer(pPager) ){
-    int rc = sqlite3ServerLock(pPager->pServer, pgno, 0);
+    int rc = sqlite3ServerLock(pPager->pServer, pgno, 0, 0);
     if( rc!=SQLITE_OK ) return rc;
   }
 #endif
@@ -5996,7 +5996,7 @@ static int pager_write(PgHdr *pPg){
 
 #ifdef SQLITE_SERVER_EDITION
   if( pagerIsServer(pPager) ){
-    rc = sqlite3ServerLock(pPager->pServer, pPg->pgno, 1);
+    rc = sqlite3ServerLock(pPager->pServer, pPg->pgno, 1, 0);
     if( rc!=SQLITE_OK ) return rc;
   }
 #endif
@@ -7669,7 +7669,7 @@ int sqlite3PagerIsServer(Pager *pPager){
   return pagerIsServer(pPager);
 }
 int sqlite3PagerPagelock(Pager *pPager, Pgno pgno, int bWrite){
-  return sqlite3ServerLock(pPager->pServer, pgno, bWrite);
+  return sqlite3ServerLock(pPager->pServer, pgno, bWrite, 0);
 }
 #endif
 
index 4ed028023d0f50954cf7bee41d3ef19335568bb5..b1508fc82babd55a85e00a5e003f88792b88d4a2 100644 (file)
@@ -356,9 +356,14 @@ int sqlite3ServerConnect(
   return rc;
 }
 
-static int serverOvercomeLock(Server *p, int bWrite, u32 v, int *pbRetry){
+static int serverOvercomeLock(
+  Server *p,                      /* Server connection */
+  int bWrite,                     /* True for a write-lock */
+  int bBlock,                     /* If true, block for this lock */
+  u32 v,                          /* Value of blocking page locking slot */
+  int *pbRetry                    /* OUT: True if caller should retry lock */
+){
   int rc = SQLITE_OK;
-  int bLocal = 0;
   int iBlock = ((int)(v>>HMA_CLIENT_SLOTS))-1;
 
   if( iBlock<0 ){
@@ -369,24 +374,32 @@ static int serverOvercomeLock(Server *p, int bWrite, u32 v, int *pbRetry){
   assert( iBlock<HMA_CLIENT_SLOTS );
 
   serverEnterMutex();
-  if( p->pHma->aClient[iBlock] ){
-    bLocal = 1;
-  }else{
+
+  if( 0==p->pHma->aClient[iBlock] ){
     rc = posixLock(p->pHma->fd, iBlock+1, SERVER_WRITE_LOCK, 0);
-  }
+    if( rc==SQLITE_OK ){
+      rc = serverRollbackClient(p, iBlock);
 
-  if( bLocal==0 && rc==SQLITE_OK ){
-    rc = serverRollbackClient(p, iBlock);
+      /* Release the lock on slot iBlock */
+      posixLock(p->pHma->fd, iBlock+1, SERVER_NO_LOCK, 0);
+      if( rc==SQLITE_OK ){
+        *pbRetry = 1;
+      }
+    }else if( rc==SQLITE_BUSY ){
+      if( bBlock ){
+        rc = posixLock(p->pHma->fd, iBlock+1, SERVER_READ_LOCK, 1);
+        if( rc==SQLITE_OK ){
+          posixLock(p->pHma->fd, iBlock+1, SERVER_NO_LOCK, 0);
+          *pbRetry = 1;
+        }
+      }
 
-    /* Release the lock on slot iBlock */
-    posixLock(p->pHma->fd, iBlock+1, SERVER_NO_LOCK, 0);
-    if( rc==SQLITE_OK ){
-      *pbRetry = 1;
+      if( rc==SQLITE_BUSY ){
+        rc = SQLITE_OK;
+      }
     }
-  }else{
-    assert( rc==SQLITE_OK || rc==SQLITE_BUSY );
-    rc = SQLITE_OK;
   }
+
   serverLeaveMutex();
 
   return rc;
@@ -396,10 +409,11 @@ static int serverOvercomeLock(Server *p, int bWrite, u32 v, int *pbRetry){
 ** Begin a transaction.
 */
 int sqlite3ServerBegin(Server *p){
-#if 0
-  return posixLock(p->pHma->fd, p->iClient+1, SERVER_WRITE_LOCK, 0);
+#if 1
+  int rc = posixLock(p->pHma->fd, p->iClient+1, SERVER_WRITE_LOCK, 1);
+  if( rc ) return rc;
 #endif
-  return sqlite3ServerLock(p, 1, 0);
+  return sqlite3ServerLock(p, 1, 0, 0);
 }
 
 /*
@@ -420,7 +434,7 @@ int sqlite3ServerEnd(Server *p){
     }
   }
   p->nLock = 0;
-#if 0
+#if 1
   return posixLock(p->pHma->fd, p->iClient+1, SERVER_READ_LOCK, 0);
 #endif
   return SQLITE_OK;
@@ -436,8 +450,11 @@ int sqlite3ServerReleaseWriteLocks(Server *p){
 
 /*
 ** Lock page pgno for reading (bWrite==0) or writing (bWrite==1).
+**
+** If parameter bBlock is non-zero, then make this a blocking lock if
+** possible.
 */
-int sqlite3ServerLock(Server *p, Pgno pgno, int bWrite){
+int sqlite3ServerLock(Server *p, Pgno pgno, int bWrite, int bBlock){
   int rc = SQLITE_OK;
 
   /* Grow the aLock[] array, if required */
@@ -475,7 +492,7 @@ int sqlite3ServerLock(Server *p, Pgno pgno, int bWrite){
 
       while( (bWrite && (v & ~(1 << p->iClient))) || (v >> HMA_CLIENT_SLOTS) ){
         int bRetry = 0;
-        rc = serverOvercomeLock(p, bWrite, v, &bRetry);
+        rc = serverOvercomeLock(p, bWrite, bBlock, v, &bRetry);
         if( rc!=SQLITE_OK ) goto server_lock_out;
         if( bRetry==0 ){
           /* There is a conflicting lock. Cannot obtain this lock. */
index 0e9632d306f06b39d9fa17add826edeb649ac9aa..d0776db99bec96c84018e532d769312f7815b80a 100644 (file)
--- a/src/wal.c
+++ b/src/wal.c
@@ -3094,7 +3094,10 @@ int sqlite3WalFrames(
   assert( pWal->writeLock || walIsServer(pWal) );
   if( pWal->writeLock==0 ){
     int bDummy = 0;
+#if 0
     rc = walLockExclusive(pWal, WAL_WRITE_LOCK, 1);
+#endif
+    rc = sqlite3ServerLock(pWal->pServer, 0, 1, 1);
     if( rc==SQLITE_OK ){
       pWal->writeLock = 1;
       rc = walIndexTryHdr(pWal, &bDummy);
@@ -3375,7 +3378,11 @@ int sqlite3WalCheckpoint(
   ** lock is successfully obtained.
   */
   if( eMode!=SQLITE_CHECKPOINT_PASSIVE ){
-    rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_WRITE_LOCK, 1);
+    if( walIsServer(pWal) ){
+      rc = sqlite3ServerLock(pWal->pServer, 0, 1, 1);
+    }else{
+      rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_WRITE_LOCK, 1);
+    }
     if( rc==SQLITE_OK ){
       pWal->writeLock = 1;
     }else if( rc==SQLITE_BUSY ){