]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Fix issues with locking_mode=EXCLUSIVE in WAL.
authordrh <drh@noemail.net>
Mon, 31 May 2010 20:28:37 +0000 (20:28 +0000)
committerdrh <drh@noemail.net>
Mon, 31 May 2010 20:28:37 +0000 (20:28 +0000)
FossilOrigin-Name: 8deba0cebd135a18da68530fab9e7d19dc21ddcb

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

index be869619553de1de6ff7cc51f658ede6f88619fa..7e0cdb20ddbc5596f82caf309eb664fac61efba2 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,8 +1,8 @@
 -----BEGIN PGP SIGNED MESSAGE-----
 Hash: SHA1
 
-C Add\san\s"isInit"\sfield\sin\sthe\swal-index\sheader\sthat\smust\sbe\snon-zero\sfor\na\svalid\sheader.\s\sUse\sthis\sto\sdetect\san\suninitialized\swal-index.
-D 2010-05-31T18:24:19
+C Fix\sissues\swith\slocking_mode=EXCLUSIVE\sin\sWAL.
+D 2010-05-31T20:28:38
 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
 F Makefile.in a5cad1f8f3e021356bfcc6c77dc16f6f1952bbc3
 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@@ -155,9 +155,9 @@ F src/os.c 1516984144e26734f97748f891f1a04f9e294c2e
 F src/os.h 6f604986f0ef0ca288c2330b16051ff70b431e8c
 F src/os_common.h a8f95b81eca8a1ab8593d23e94f8a35f35d4078f
 F src/os_os2.c 665876d5eec7585226b0a1cf5e18098de2b2da19
-F src/os_unix.c 18ed6016685593e23c0e559804dd391a030dfb62
+F src/os_unix.c 129e60ccca3abe59ca4374e28138c540c1069a09
 F src/os_win.c f815403c51a2adad30244374c801dd7fd2734567
-F src/pager.c f7128f02623beab9462ca6e73516cf73c49186f8
+F src/pager.c acbef227bf158776449907c275c5d9332e4e52f9
 F src/pager.h 76466c3a5af56943537f68b1f16567101a0cd1d0
 F src/parse.y ace5c7a125d9f2a410e431ee3209034105045f7e
 F src/pcache.c ace8f6a5ecd4711cc66a1b23053be7109bd437cf
@@ -227,7 +227,7 @@ F src/vdbeblob.c 5327132a42a91e8b7acfb60b9d2c3b1c5c863e0e
 F src/vdbemem.c 2a82f455f6ca6f78b59fb312f96054c04ae0ead1
 F src/vdbetrace.c 864cef96919323482ebd9986f2132435115e9cc2
 F src/vtab.c a0f8a40274e4261696ef57aa806de2776ab72cda
-F src/wal.c a20a069a7ed79ea16cccbf0d83a34d5e2a7250a6
+F src/wal.c b3f312fe54d298f965de98870af9eae0c5829310
 F src/wal.h 1c1c9feb629b7f4afcbe0b47f80f47c5551d3a02
 F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f
 F src/where.c 75fee9e255b62f773fcadd1d1f25b6f63ac7a356
@@ -818,14 +818,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
 F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
-P 552658da2845c2323167b6c7db6e5c00090f280c
-R cd1f6d6abaca428c2e0680ad6a01cc30
+P a16fde190183d1ae252d1aa305b23fdb88c603dc
+R 7ca4bba7f34b45ef2eb156ca8f31e257
 U drh
-Z 611237a4cf581f565db3251639fe3292
+Z 95075c06905af9e6fca1be95088ee79b
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.4.6 (GNU/Linux)
 
-iD8DBQFMA/7XoxKgR168RlERAvMDAJ41dyIAjGkayTRj8Kw2ioAehVpN+QCfbTwC
-9y9JhOrCL2VhmOxcK/DziJQ=
-=4aF+
+iD8DBQFMBBv5oxKgR168RlERAmKCAJ953sKjjyeIhzGjYESyG8xuJ6EZyQCfcwsk
+dvi+rRNsOxQx96r9i6h2uoU=
+=APx0
 -----END PGP SIGNATURE-----
index 76a2a6d7bca83062cec161787f6008614b9ede0d..469b85a5d54b0a9fbd1b2b73b35caa28325db484 100644 (file)
@@ -1 +1 @@
-a16fde190183d1ae252d1aa305b23fdb88c603dc
\ No newline at end of file
+8deba0cebd135a18da68530fab9e7d19dc21ddcb
\ No newline at end of file
index 91f641e05720996a299c0128b5fdba5ecb2f7d27..c6ca5fc4687a3cfd9724ff4bdcd47501d4922792 100644 (file)
@@ -3399,10 +3399,6 @@ static int unixShmClose(
   assert( pShmNode==pDbFd->pInode->pShmNode );
   assert( pShmNode->pInode==pDbFd->pInode );
 
-  /* Verify that the connection being closed holds no locks */
-  assert( p->exclMask==0 );
-  assert( p->sharedMask==0 );
-
   /* Remove connection p from the set of connections associated
   ** with pShmNode */
   sqlite3_mutex_enter(pShmNode->mutex);
index a88ec5cab99aa6dfb8de199b0ec3e8df4840791c..3eb123348397aa66a4081388620151c5b61a8acb 100644 (file)
@@ -1445,9 +1445,8 @@ static int pager_end_transaction(Pager *pPager, int hasMaster){
     */
     if( rc2==SQLITE_OK 
      && !pPager->exclusiveMode 
-     && sqlite3WalExclusiveMode(pPager->pWal, -1
+     && sqlite3WalExclusiveMode(pPager->pWal, 0
     ){
-      sqlite3WalExclusiveMode(pPager->pWal, 0);
       rc2 = osUnlock(pPager->fd, SHARED_LOCK);
     }
   }else if( !pPager->exclusiveMode ){
@@ -2375,6 +2374,13 @@ static int pagerBeginReadTransaction(Pager *pPager){
 
   assert( pagerUseWal(pPager) );
 
+  /* sqlite3WalEndReadTransaction() was not called for the previous
+  ** transaction in locking_mode=EXCLUSIVE.  So call it now.  If we
+  ** are in locking_mode=NORMAL and EndRead() was previously called,
+  ** the duplicate call is harmless.
+  */
+  sqlite3WalEndReadTransaction(pPager->pWal);
+
   rc = sqlite3WalBeginReadTransaction(pPager->pWal, &changed);
   if( rc==SQLITE_OK ){
     int dummy;
@@ -4546,7 +4552,7 @@ int sqlite3PagerBegin(Pager *pPager, int exFlag, int subjInMemory){
       /* If the pager is configured to use locking_mode=exclusive, and an
       ** exclusive lock on the database is not already held, obtain it now.
       */
-      if( pPager->exclusiveMode && !sqlite3WalExclusiveMode(pPager->pWal, -1) ){
+      if( pPager->exclusiveMode && sqlite3WalExclusiveMode(pPager->pWal, -1) ){
         rc = sqlite3OsLock(pPager->fd, EXCLUSIVE_LOCK);
         pPager->state = PAGER_SHARED;
         if( rc!=SQLITE_OK ){
index 9801565c3e48c7a15af849f8e2dae470b322e20d..99d884c4635b5e028974531e1db9c301b6643327 100644 (file)
--- a/src/wal.c
+++ b/src/wal.c
@@ -1693,7 +1693,7 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal){
   int i;                          /* Loop counter */
   int rc;                         /* Return code  */
 
-  assert( pWal->readLock<0 );  /* No read lock held on entry */
+  assert( pWal->readLock<0 );     /* Not currently locked */
 
   if( !useWal ){
     rc = walIndexReadHdr(pWal, pChanged);
@@ -2350,29 +2350,54 @@ int sqlite3WalCallback(Wal *pWal){
 }
 
 /*
-** This function is called to set or query the exclusive-mode flag 
-** associated with the WAL connection passed as the first argument. The
-** exclusive-mode flag should be set to indicate that the caller is
-** holding an EXCLUSIVE lock on the database file (it does this in
-** locking_mode=exclusive mode). If the EXCLUSIVE lock is to be dropped,
-** the flag set by this function should be cleared before doing so.
-**
-** When the flag is set, this module does not call the VFS xShmLock()
-** method to obtain any locks on the wal-index (as it assumes it
-** has exclusive access to the wal and wal-index files anyhow). It
-** continues to hold (and does not drop) the existing READ lock on
-** the wal-index.
-**
-** To set or clear the flag, the "op" parameter is passed 1 or 0,
-** respectively. To query the flag, pass -1. In all cases, the value
-** returned is the value of the exclusive-mode flag (after its value
-** has been modified, if applicable).
+** This function is called to change the WAL subsystem into or out
+** of locking_mode=EXCLUSIVE.
+**
+** If op is zero, then attempt to change from locking_mode=EXCLUSIVE
+** into locking_mode=NORMAL.  This means that we must acquire a lock
+** on the pWal->readLock byte.  If the WAL is already in locking_mode=NORMAL
+** or if the acquisition of the lock fails, then return 0.  If the
+** transition out of exclusive-mode is successful, return 1.  This
+** operation must occur while the pager is still holding the exclusive
+** lock on the main database file.
+**
+** If op is one, then change from locking_mode=NORMAL into 
+** locking_mode=EXCLUSIVE.  This means that the pWal->readLock must
+** be released.  Return 1 if the transition is made and 0 if the
+** WAL is already in exclusive-locking mode - meaning that this
+** routine is a no-op.  The pager must already hold the exclusive lock
+** on the main database file before invoking this operation.
+**
+** If op is negative, then do a dry-run of the op==1 case but do
+** not actually change anything.  The pager uses this to see if it
+** should acquire the database exclusive lock prior to invoking
+** the op==1 case.
 */
 int sqlite3WalExclusiveMode(Wal *pWal, int op){
-  if( op>=0 ){
-    pWal->exclusiveMode = (u8)op;
+  int rc;
+  assert( pWal->writeLock==0 && pWal->readLock>=0 );
+  if( op==0 ){
+    if( pWal->exclusiveMode ){
+      pWal->exclusiveMode = 0;
+      if( walLockShared(pWal, WAL_READ_LOCK(pWal->readLock))!=SQLITE_OK ){
+        pWal->exclusiveMode = 1;
+      }
+      rc = pWal->exclusiveMode==0;
+    }else{
+      /* No changes.  Either already in locking_mode=NORMAL or else the 
+      ** acquisition of the read-lock failed.  The pager must continue to
+      ** hold the database exclusive lock. */
+      rc = 0;
+    }
+  }else if( op>0 ){
+    assert( pWal->exclusiveMode==0 );
+    walUnlockShared(pWal, WAL_READ_LOCK(pWal->readLock));
+    pWal->exclusiveMode = 1;
+    rc = 1;
+  }else{
+    rc = pWal->exclusiveMode==0;
   }
-  return pWal->exclusiveMode;
+  return rc;
 }
 
 #endif /* #ifndef SQLITE_OMIT_WAL */