]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Simplify the wal-readonly branch so that it does not require changes to
authordrh <drh@noemail.net>
Wed, 1 Jun 2011 20:01:49 +0000 (20:01 +0000)
committerdrh <drh@noemail.net>
Wed, 1 Jun 2011 20:01:49 +0000 (20:01 +0000)
anything other than os_unix.c and wal.c and a couple of new error codes.

FossilOrigin-Name: d6b4709de4d1f8af001f58938247f00a652a616e

12 files changed:
manifest
manifest.uuid
src/attach.c
src/btree.h
src/main.c
src/os_unix.c
src/pager.c
src/pager.h
src/sqlite.h.in
src/sqliteInt.h
src/wal.c
src/wal.h

index b3a84d3a3f531f04768d08a431fe52e04f8a8163..8b6e11236ed861dd76e1b6d82fce78d26aa7e310 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Pull\sthe\slatest\strunk\schanges\sinto\sthe\swal-readonly\sbranch.
-D 2011-06-01T19:44:57.308
+C Simplify\sthe\swal-readonly\sbranch\sso\sthat\sit\sdoes\snot\srequire\schanges\sto\nanything\sother\sthan\sos_unix.c\sand\swal.c\sand\sa\scouple\sof\snew\serror\scodes.
+D 2011-06-01T20:01:49.650
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in 11dcc00a8d0e5202def00e81732784fb0cc4fe1d
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -117,13 +117,13 @@ F sqlite3.1 6be1ad09113570e1fc8dcaff84c9b0b337db5ffc
 F sqlite3.pc.in ae6f59a76e862f5c561eb32a380228a02afc3cad
 F src/alter.c 280f5c04b11b492703a342222b3de0a999445280
 F src/analyze.c a425d62e8fa9ebcb4359ab84ff0c62c6563d2e2a
-F src/attach.c a87bfb77a720f7aa02791434aacfd9bc8feb50cc
+F src/attach.c 12c6957996908edc31c96d7c68d4942c2474405f
 F src/auth.c 523da7fb4979469955d822ff9298352d6b31de34
 F src/backup.c 986c15232757f2873dff35ee3b35cbf935fc573c
 F src/bitvec.c af50f1c8c0ff54d6bdb7a80e2fceca5a93670bef
 F src/btmutex.c 976f45a12e37293e32cae0281b15a21d48a8aaa7
 F src/btree.c 0d3b39dcb79565c053e35fc12713f12d8a74d6a9
-F src/btree.h d796dc4030b3cce7f5a0cc4f2f986d2befa6b8ac
+F src/btree.h f5d775cd6cfc7ac32a2535b70e8d2af48ef5f2ce
 F src/btreeInt.h 67978c014fa4f7cc874032dd3aacadd8db656bc3
 F src/build.c c10ab9e2c77ade99dee23554787f8acfc0c231fc
 F src/callback.c 0425c6320730e6d3981acfb9202c1bed9016ad1a
@@ -144,7 +144,7 @@ F src/journal.c 552839e54d1bf76fb8f7abe51868b66acacf6a0e
 F src/legacy.c a199d7683d60cef73089e892409113e69c23a99f
 F src/lempar.c 7f026423f4d71d989e719a743f98a1cbd4e6d99e
 F src/loadext.c 3ae0d52da013a6326310655be6473fd472347b85
-F src/main.c 4e55ff4800181e3ad063492740f54ce406de5deb
+F src/main.c 059daeed5876b3604f0192f838faf5f4db138901
 F src/malloc.c 591aedb20ae40813f1045f2ef253438a334775d9
 F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645
 F src/mem1.c 00bd8265c81abb665c48fea1e0c234eb3b922206
@@ -163,10 +163,10 @@ F src/os.c 22ac61d06e72a0dac900400147333b07b13d8e1d
 F src/os.h 9dbed8c2b9c1f2f2ebabc09e49829d4777c26bf9
 F src/os_common.h a8f95b81eca8a1ab8593d23e94f8a35f35d4078f
 F src/os_os2.c 4a75888ba3dfc820ad5e8177025972d74d7f2440
-F src/os_unix.c af3c3f6a0fc6dbde802e55848f1cad7fb2121ff3
+F src/os_unix.c a59c0718021934157f235468788c793cbc0d53de
 F src/os_win.c 218b899469e570d46eb8147c2383075f7c026230
-F src/pager.c 2cf3bad86e6fbac42d9dbd3b89799185a343b17b
-F src/pager.h 34c6b029446f06f40847746d22faac0d354dd909
+F src/pager.c 120550e7ef01dafaa2cbb4a0528c0d87c8f12b41
+F src/pager.h 3f8c783de1d4706b40b1ac15b64f5f896bcc78d1
 F src/parse.y 12b7ebd61ea54f0e1b1083ff69cc2c8ce9353d58
 F src/pcache.c 49e718c095810c6b3334e3a6d89970aceaddefce
 F src/pcache.h c683390d50f856d4cd8e24342ae62027d1bb6050
@@ -179,9 +179,9 @@ F src/resolve.c 1c0f32b64f8e3f555fe1f732f9d6f501a7f05706
 F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697
 F src/select.c d9d440809025a58547e39f4f268c2a296bfb56ff
 F src/shell.c decd04236a7ef26be5ef46d4ea963044bfad9a48
-F src/sqlite.h.in dbe88418628302c0a93671a216346acb5746211a
+F src/sqlite.h.in 2f51e4f58b2b4626fcbd9938580e730cb5fb4985
 F src/sqlite3ext.h c90bd5507099f62043832d73f6425d8d5c5da754
-F src/sqliteInt.h 219b21e80f46eef7cc7bb7477c12de61d00f5607
+F src/sqliteInt.h 6e58c558c57c8f44011736d5fa5295eb3130f9de
 F src/sqliteLimit.h 164b0e6749d31e0daa1a4589a169d31c0dec7b3d
 F src/status.c 7ac64842c86cec2fc1a1d0e5c16d3beb8ad332bf
 F src/table.c 2cd62736f845d82200acfa1287e33feb3c15d62e
@@ -245,8 +245,8 @@ F src/vdbeblob.c f024f0bf420f36b070143c32b15cc7287341ffd3
 F src/vdbemem.c 0498796b6ffbe45e32960d6a1f5adfb6e419883b
 F src/vdbetrace.c 5d0dc3d5fd54878cc8d6d28eb41deb8d5885b114
 F src/vtab.c 9ba8c7fdb7d39260c033a402f6032d3e7bc5d336
-F src/wal.c 861ea98779dac3867e5f97d13e61cbbb39b310b0
-F src/wal.h 0835021ae243c2f1119e997e8af5d8cc3b991de1
+F src/wal.c fd63d07233203dd3bd29cbe1ae5c8bb2c34e08fc
+F src/wal.h 66b40bd91bc29a5be1c88ddd1f5ade8f3f48728a
 F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f
 F src/where.c 55403ce19c506be6a321c7f129aff693d6103db5
 F test/8_3_names.test b93687beebd17f6ebf812405a6833bae5d1f4199
@@ -939,7 +939,7 @@ F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
 F tool/split-sqlite3c.tcl d9be87f1c340285a3e081eb19b4a247981ed290c
 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
-P 2c6b5a28e3f6b7cb96b944d0a254f3707885f1ce e704e8690ae35decc9769a45cf8d519ccad8b79d
-R 5f4edf2ff77d011b562e3dc234f8f21d
+P 0b63b71357a65e26ecd3f3bb34a5f14feee322f4
+R 20a045d8e6470f5f17b67b2f15ff8859
 U drh
-Z 99212444a62258034d706d358ee0a50e
+Z f7b3b70c555e3fb5f3360ed8e60c2877
index 70ad59250f9ac946a4d05b923feceb458ac81819..6f393899aa7a6da559c649fb4bb15fd8fe5b8382 100644 (file)
@@ -1 +1 @@
-0b63b71357a65e26ecd3f3bb34a5f14feee322f4
\ No newline at end of file
+d6b4709de4d1f8af001f58938247f00a652a616e
\ No newline at end of file
index 4b8ea7791773119b48f00bbd5192a558215b1150..18f8823b314f0b5b632d7139df6c1207259b2630 100644 (file)
@@ -76,8 +76,6 @@ static void attachFunc(
   Db *aNew;
   char *zErrDyn = 0;
   sqlite3_vfs *pVfs;
-  const char *zVfs = db->pVfs->zName;       /* Name of default (main) VFS */
-  int btflags = 0;
 
   UNUSED_PARAMETER(NotUsed);
 
@@ -131,7 +129,7 @@ static void attachFunc(
   ** or may not be initialised.
   */
   flags = db->openFlags;
-  rc = sqlite3ParseUri(zVfs, zFile, &flags, &btflags, &pVfs, &zPath, &zErr);
+  rc = sqlite3ParseUri(db->pVfs->zName, zFile, &flags, &pVfs, &zPath, &zErr);
   if( rc!=SQLITE_OK ){
     if( rc==SQLITE_NOMEM ) db->mallocFailed = 1;
     sqlite3_result_error(context, zErr, -1);
@@ -140,7 +138,7 @@ static void attachFunc(
   }
   assert( pVfs );
   flags |= SQLITE_OPEN_MAIN_DB;
-  rc = sqlite3BtreeOpen(pVfs, zPath, db, &aNew->pBt, btflags, flags);
+  rc = sqlite3BtreeOpen(pVfs, zPath, db, &aNew->pBt, 0, flags);
   sqlite3_free( zPath );
   db->nDb++;
   if( rc==SQLITE_CONSTRAINT ){
index c5abc9c865e283aded4d348012bb992e29839c02..9e3a73b3b64d98cafdd9e7afbfa2d7b0210e0ef6 100644 (file)
@@ -61,7 +61,6 @@ int sqlite3BtreeOpen(
 #define BTREE_MEMORY        4  /* This is an in-memory DB */
 #define BTREE_SINGLE        8  /* The file contains at most 1 b-tree */
 #define BTREE_UNORDERED    16  /* Use of a hash implementation is OK */
-#define BTREE_READONLYSHM  32  /* Read-only SHM access is acceptable */
 
 int sqlite3BtreeClose(Btree*);
 int sqlite3BtreeSetCacheSize(Btree*,int);
index cdd54b659df2be999b58aa2c13268ae2271851b4..c99d3965468527533e46635a2ee3854f81375d6e 100644 (file)
@@ -1803,11 +1803,6 @@ int sqlite3_limit(sqlite3 *db, int limitId, int newLimit){
 ** *pFlags may be updated before returning if the URI filename contains 
 ** "cache=xxx" or "mode=xxx" query parameters.
 **
-** The third argument, pBtflags, points to an integer containing the flags
-** that will be passed as the 5th argument to sqlite3BtreeOpen (BTREE_XXX
-** flags). This value will be edited if the URI filename contains a
-** "readonly_shm=1" or "readonly_shm=0" query parameter.
-**
 ** If successful, SQLITE_OK is returned. In this case *ppVfs is set to point to
 ** the VFS that should be used to open the database file. *pzFile is set to
 ** point to a buffer containing the name of the file to open. It is the 
@@ -1823,7 +1818,6 @@ int sqlite3ParseUri(
   const char *zDefaultVfs,        /* VFS to use if no "vfs=xxx" query option */
   const char *zUri,               /* Nul-terminated URI to parse */
   unsigned int *pFlags,           /* IN/OUT: SQLITE_OPEN_XXX flags */
-  int *pBtflags,                  /* IN/OUT: BTREE_XXX flags */
   sqlite3_vfs **ppVfs,            /* OUT: VFS to use */ 
   char **pzFile,                  /* OUT: Filename component of URI */
   char **pzErrMsg                 /* OUT: Error message (if rc!=SQLITE_OK) */
@@ -1939,12 +1933,6 @@ int sqlite3ParseUri(
 
       if( nOpt==3 && memcmp("vfs", zOpt, 3)==0 ){
         zVfs = zVal;
-      }else if( nOpt==12 && memcmp("readonly_shm", zOpt, 12)==0 ){
-        if( sqlite3Atoi(zVal) ){
-          *pBtflags |= BTREE_READONLYSHM;
-        }else{
-          *pBtflags &= ~BTREE_READONLYSHM;
-        }
       }else{
         struct OpenMode {
           const char *z;
@@ -2048,7 +2036,6 @@ static int openDatabase(
   int isThreadsafe;               /* True for threadsafe connections */
   char *zOpen = 0;                /* Filename argument to pass to BtreeOpen() */
   char *zErrMsg = 0;              /* Error message from sqlite3ParseUri() */
-  int btflags = 0;                /* Mask of BTREE_XXX flags */
 
   *ppDb = 0;
 #ifndef SQLITE_OMIT_AUTOINIT
@@ -2177,8 +2164,7 @@ static int openDatabase(
 
   /* Parse the filename/URI argument. */
   db->openFlags = flags;
-  rc = sqlite3ParseUri(
-      zVfs, zFilename, &flags, &btflags, &db->pVfs, &zOpen, &zErrMsg);
+  rc = sqlite3ParseUri(zVfs, zFilename, &flags, &db->pVfs, &zOpen, &zErrMsg);
   if( rc!=SQLITE_OK ){
     if( rc==SQLITE_NOMEM ) db->mallocFailed = 1;
     sqlite3Error(db, rc, zErrMsg ? "%s" : 0, zErrMsg);
@@ -2187,7 +2173,7 @@ static int openDatabase(
   }
 
   /* Open the backend database driver */
-  rc = sqlite3BtreeOpen(db->pVfs, zOpen, db, &db->aDb[0].pBt, btflags,
+  rc = sqlite3BtreeOpen(db->pVfs, zOpen, db, &db->aDb[0].pBt, 0,
                         flags | SQLITE_OPEN_MAIN_DB);
   if( rc!=SQLITE_OK ){
     if( rc==SQLITE_IOERR_NOMEM ){
index 947f431aebe2de17fca3824e2a025bf8d9b04761..e6d1774a49acdebb0fa9559939f2c05589468613 100644 (file)
@@ -212,7 +212,6 @@ struct unixFile {
   UnixUnusedFd *pUnused;              /* Pre-allocated UnixUnusedFd */
   const char *zPath;                  /* Name of the file */
   unixShm *pShm;                      /* Shared memory segment information */
-  int readOnlyShm;                    /* True to open shared-memory read-only */
   int szChunk;                        /* Configured by FCNTL_CHUNK_SIZE */
 #if SQLITE_ENABLE_LOCKING_STYLE
   int openFlags;                      /* The flags specified at open() */
@@ -3453,10 +3452,6 @@ static int unixFileControl(sqlite3_file *id, int op, void *pArg){
     case SQLITE_FCNTL_SIZE_HINT: {
       return fcntlSizeHint((unixFile *)id, *(i64 *)pArg);
     }
-    case SQLITE_FCNTL_READONLY_SHM: {
-      ((unixFile*)id)->readOnlyShm = (pArg!=0);
-      return SQLITE_OK;
-    }
 #ifndef NDEBUG
     /* The pager calls this method to signal that it has done
     ** a rollback and that the database is therefore unchanged and
@@ -3542,11 +3537,11 @@ struct unixShmNode {
   char *zFilename;           /* Name of the mmapped file */
   int h;                     /* Open file descriptor */
   int szRegion;              /* Size of shared-memory regions */
-  int nRegion;               /* Size of array apRegion */
+  u16 nRegion;               /* Size of array apRegion */
+  u8 isReadonly;             /* True if read-only */
   char **apRegion;           /* Array of mapped shared-memory regions */
   int nRef;                  /* Number of unixShm objects pointing to this */
   unixShm *pFirst;           /* All unixShm objects pointing to this */
-  u8 readOnly;               /* True if this is a read-only mapping */
 #ifdef SQLITE_DEBUG
   u8 exclMask;               /* Mask of exclusive locks held */
   u8 sharedMask;             /* Mask of shared locks held */
@@ -3787,48 +3782,38 @@ static int unixOpenSharedMemory(unixFile *pDbFd){
     }
 
     if( pInode->bProcessLock==0 ){
-      int flags = (pDbFd->readOnlyShm ? O_RDONLY : O_RDWR|O_CREAT);
-      pShmNode->h = robust_open(zShmFilename, flags, (sStat.st_mode & 0777));
+      pShmNode->h = robust_open(zShmFilename, O_RDWR|O_CREAT,
+                               (sStat.st_mode & 0777));
       if( pShmNode->h<0 ){
-        rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShmFilename);
-        goto shm_open_err;
+        const char *zRO;
+        zRO = sqlite3_uri_parameter(pDbFd->zPath, "readonly_shm");
+        if( zRO && (zRO[0]!='0' || zRO[1]!=0) ){
+          pShmNode->h = robust_open(zShmFilename, O_RDONLY,
+                                    (sStat.st_mode & 0777));
+          pShmNode->isReadonly = 1;
+        }
+        if( pShmNode->h<0 ){
+          rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShmFilename);
+          goto shm_open_err;
+        }
       }
-      pShmNode->readOnly = pDbFd->readOnlyShm;
   
       /* Check to see if another process is holding the dead-man switch.
-      ** If not, zero the first few bytes of the shared-memory file to make
-      ** sure it is not mistaken for valid by code in wal.c. Except, if this 
-      ** is a read-only connection to the shared-memory then it is not possible
-      ** to check check if another process is holding a read-lock on the DMS
-      ** byte, as we cannot attempt a write-lock via a read-only file 
-      ** descriptor. So in this case, we just assume the shared-memory 
-      ** contents are Ok and proceed.  */
-      if( pShmNode->readOnly==0 ){
-        rc = SQLITE_OK;
-        if( unixShmSystemLock(pShmNode, F_WRLCK, UNIX_SHM_DMS, 1)==SQLITE_OK ){
-          if( pDbFd->readOnlyShm ){
-            rc = SQLITE_IOERR_SHMOPEN;
-          }else if( 4!=osWrite(pShmNode->h, "\00\00\00\00", 4) ){
-            rc = unixLogError(SQLITE_IOERR_SHMOPEN, "ftruncate", zShmFilename);
-          }
-        }
-        if( rc==SQLITE_OK ){
-          rc = unixShmSystemLock(pShmNode, F_RDLCK, UNIX_SHM_DMS, 1);
+      ** If not, truncate the file to zero length. 
+      */
+      rc = SQLITE_OK;
+      if( unixShmSystemLock(pShmNode, F_WRLCK, UNIX_SHM_DMS, 1)==SQLITE_OK ){
+        if( robust_ftruncate(pShmNode->h, 0) ){
+          rc = unixLogError(SQLITE_IOERR_SHMOPEN, "ftruncate", zShmFilename);
         }
-        if( rc ) goto shm_open_err;
       }
+      if( rc==SQLITE_OK ){
+        rc = unixShmSystemLock(pShmNode, F_RDLCK, UNIX_SHM_DMS, 1);
+      }
+      if( rc ) goto shm_open_err;
     }
   }
 
-  /* If the unixShmNode is read-only, but SQLITE_FCNTL_READONLY_SHM has not
-  ** been set for file-descriptor pDbFd, return an error. The wal.c module
-  ** will then call this function again with SQLITE_FCNTL_READONLY_SHM set.
-  */
-  else if( pShmNode->readOnly && !pDbFd->readOnlyShm ){
-    rc = SQLITE_IOERR_SHMOPEN;
-    goto shm_open_err;
-  }
-
   /* Make the new connection a child of the unixShmNode */
   p->pShmNode = pShmNode;
 #ifdef SQLITE_DEBUG
@@ -3949,7 +3934,8 @@ static int unixShmMap(
     while(pShmNode->nRegion<=iRegion){
       void *pMem;
       if( pShmNode->h>=0 ){
-        pMem = mmap(0, szRegion, PROT_READ|(!pShmNode->readOnly?PROT_WRITE:0), 
+        pMem = mmap(0, szRegion,
+            pShmNode->isReadonly ? PROT_READ : PROT_READ|PROT_WRITE, 
             MAP_SHARED, pShmNode->h, pShmNode->nRegion*szRegion
         );
         if( pMem==MAP_FAILED ){
@@ -3975,6 +3961,7 @@ shmpage_out:
   }else{
     *pp = 0;
   }
+  if( pShmNode->isReadonly && rc==SQLITE_OK ) rc = SQLITE_READONLY;
   sqlite3_mutex_leave(pShmNode->mutex);
   return rc;
 }
index 461c735432e5c9876f3c4c2ea65025980ef7524e..7ff9a9a000aaaa21041910a0d28f4fe572f3068b 100644 (file)
@@ -620,7 +620,6 @@ struct Pager {
   u8 tempFile;                /* zFilename is a temporary file */
   u8 readOnly;                /* True for a read-only database */
   u8 memDb;                   /* True to inhibit all file I/O */
-  u8 readOnlyShm;             /* True if read-only shm access is Ok */
 
   /**************************************************************************
   ** The following block contains those class members that change during
@@ -3018,7 +3017,6 @@ static int pagerWalFrames(
 static int pagerBeginReadTransaction(Pager *pPager){
   int rc;                         /* Return code */
   int changed = 0;                /* True if cache must be reset */
-  Wal *pWal = pPager->pWal;
 
   assert( pagerUseWal(pPager) );
   assert( pPager->eState==PAGER_OPEN || pPager->eState==PAGER_READER );
@@ -3028,9 +3026,9 @@ static int pagerBeginReadTransaction(Pager *pPager){
   ** are in locking_mode=NORMAL and EndRead() was previously called,
   ** the duplicate call is harmless.
   */
-  sqlite3WalEndReadTransaction(pWal);
+  sqlite3WalEndReadTransaction(pPager->pWal);
 
-  rc = sqlite3WalBeginReadTransaction(pWal, pPager->readOnlyShm, &changed);
+  rc = sqlite3WalBeginReadTransaction(pPager->pWal, &changed);
   if( rc!=SQLITE_OK || changed ){
     pager_reset(pPager);
   }
@@ -4418,7 +4416,6 @@ int sqlite3PagerOpen(
   }
   pPager->pVfs = pVfs;
   pPager->vfsFlags = vfsFlags;
-  pPager->readOnlyShm = (flags & PAGER_READONLYSHM)!=0;
 
   /* Open the pager file.
   */
index c6cb8bcb557ee0efa1848a6816e2b3d1908010e4..eab7ddaf80bb44c3a89c1b7123a8691be19b64fb 100644 (file)
@@ -60,7 +60,6 @@ typedef struct PgHdr DbPage;
 #define PAGER_OMIT_JOURNAL  0x0001    /* Do not use a rollback journal */
 #define PAGER_NO_READLOCK   0x0002    /* Omit readlocks on readonly files */
 #define PAGER_MEMORY        0x0004    /* In-memory database */
-#define PAGER_READONLYSHM   0x0020    /* Read-only SHM access is acceptable */
 
 /*
 ** Valid values for the second argument to sqlite3PagerLockingMode().
index 45aec0e1c2e8d49ee7f3f1fff999e789a1250287..593e9148fe419c11fd84fb095189ca2de79e3cd7 100644 (file)
@@ -454,7 +454,6 @@ int sqlite3_exec(
 #define SQLITE_BUSY_RECOVERY           (SQLITE_BUSY   |  (1<<8))
 #define SQLITE_CANTOPEN_NOTEMPDIR      (SQLITE_CANTOPEN | (1<<8))
 #define SQLITE_CORRUPT_VTAB            (SQLITE_CORRUPT | (1<<8))
-
 #define SQLITE_READONLY_RECOVERY       (SQLITE_READONLY | (1<<8))
 #define SQLITE_READONLY_CANTLOCK       (SQLITE_READONLY | (2<<8))
 
@@ -737,27 +736,6 @@ struct sqlite3_io_methods {
 ** Applications should not call [sqlite3_file_control()] with this
 ** opcode as doing so may disrupt the operation of the specialized VFSes
 ** that do require it.  
-**
-** The [SQLITE_FCNTL_READONLY_SHM] may be generated internally by SQLite if
-** the "readonly_shm=1" URI option is specified when the database is opened.
-** The fourth argument passed to the VFS xFileControl methods is a pointer
-** to a variable of type "int" containing the value 1 or 0. If the variable
-** contains the value 1, then this indicates to the VFS that a read-only
-** mapping of the shared-memory region is acceptable. If it is set to 0, then
-** this indicates that a read-write mapping is required (as normal). If
-** a read-only mapping is returned, then the VFS may also return read-only
-** mappings for any subsequent requests via the same file-descriptor -
-** regardless of the value most recently configured using
-** SQLITE_FCNTL_READONLY_SHM.
-**
-** In practice, if "readonly_shm=1" is specified and the first attempt to
-** map a shared-memory region fails, then this file-control is invoked with
-** the argument variable set to 1 and a second attempt to map the shared-memory
-** region is made. If this mapping succeeds, then the connection continues
-** with the read-only mapping. Otherwise, if it fails, SQLITE_CANTOPEN is
-** returned to the caller. Whether or not the second (read-only) mapping
-** attempt succeeds, the file-control is invoked again with the argument
-** variable set to 0.
 */
 #define SQLITE_FCNTL_LOCKSTATE        1
 #define SQLITE_GET_LOCKPROXYFILE      2
@@ -767,7 +745,6 @@ struct sqlite3_io_methods {
 #define SQLITE_FCNTL_CHUNK_SIZE       6
 #define SQLITE_FCNTL_FILE_POINTER     7
 #define SQLITE_FCNTL_SYNC_OMITTED     8
-#define SQLITE_FCNTL_READONLY_SHM     9
 
 
 /*
@@ -2481,7 +2458,7 @@ void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
 ** [[core URI query parameters]]
 ** The query component of a URI may contain parameters that are interpreted
 ** either by SQLite itself, or by a [VFS | custom VFS implementation].
-** SQLite interprets the following four query parameters:
+** SQLite interprets the following three query parameters:
 **
 ** <ul>
 **   <li> <b>vfs</b>: ^The "vfs" parameter may be used to specify the name of
@@ -2513,22 +2490,6 @@ void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
 **     ^If sqlite3_open_v2() is used and the "cache" parameter is present in
 **     a URI filename, its value overrides any behaviour requested by setting
 **     SQLITE_OPEN_PRIVATECACHE or SQLITE_OPEN_SHAREDCACHE flag.
-**
-**   <li> <b>readonly_shm</b>: ^The readonly_shm parameter may be set to 
-**     either "1" or "0". Setting it to "1" indicates that if the database
-**     is in WAL mode and read-write access to the associated shared 
-**     memory region cannot be obtained, then an attempt should be made to open
-**     the shared-memory in read-only mode instead. If there exist one or
-**     more other database clients that have read-write connections to the
-**     database shared-memory, then a read-only shared-memory connection works 
-**     fine. However, if there exist no clients with read-write connections 
-**     to the shared-memory and the most recent such crashed or was interrupted
-**     by a power failure, then it is possible for a database client using a
-**     read-only connection to return incorrect data, incorrectly report 
-**     database corruption, or return an SQLITE_READONLY error. Or if the
-**     most recent read-write connection shut down cleanly, it may not be
-**     possible to open the shared-memory in read-only mode at all, and SQLite
-**     will return SQLITE_CANTOPEN.
 ** </ul>
 **
 ** ^Specifying an unknown parameter in the query component of a URI is not an
index 8b0aa855d874cc854a4de37214b994133a889f8b..fd86158e00fb29f843ded27fb205e71ebbcc9575 100644 (file)
@@ -2673,7 +2673,7 @@ void sqlite3AddColumnType(Parse*,Token*);
 void sqlite3AddDefaultValue(Parse*,ExprSpan*);
 void sqlite3AddCollateType(Parse*, Token*);
 void sqlite3EndTable(Parse*,Token*,Token*,Select*);
-int sqlite3ParseUri(const char*,const char*,unsigned int*,int*,
+int sqlite3ParseUri(const char*,const char*,unsigned int*,
                     sqlite3_vfs**,char**,char **);
 
 Bitvec *sqlite3BitvecCreate(u32);
index 87d3fcc968a514909e6d6c0dc9e18202d0069751..9f9e1115fa86796273aaa9ad5707eca582f34c60 100644 (file)
--- a/src/wal.c
+++ b/src/wal.c
@@ -406,14 +406,6 @@ struct WalCkptInfo {
 /*
 ** An open write-ahead log file is represented by an instance of the
 ** following object.
-**
-** The readOnlyShm variable is normally set to 0. If it is set to 1, then
-** the connection to shared-memory is read-only. This means it cannot
-** be written at all (even when read-locking the database). If it is set
-** to 2, then the shared-memory region is not yet open, but a read-only
-** connection is acceptable. In this case when the shared-memory is opened
-** (see function walIndexPage()), readOnlyShm is set to either 0 or 1 as
-** appropriate.
 */
 struct Wal {
   sqlite3_vfs *pVfs;         /* The VFS used to create pDbFd */
@@ -428,8 +420,7 @@ struct Wal {
   u8 exclusiveMode;          /* Non-zero if connection is in exclusive mode */
   u8 writeLock;              /* True if in a write transaction */
   u8 ckptLock;               /* True if holding a checkpoint lock */
-  u8 readOnly;               /* True if the WAL file is open read-only */
-  u8 readOnlyShm;            /* True if the SHM file is open read-only */
+  u8 readOnly;               /* WAL_RDWR, WAL_RDONLY, or WAL_SHM_RDONLY */
   WalIndexHdr hdr;           /* Wal-index header for current transaction */
   const char *zWalName;      /* Name of WAL file */
   u32 nCkpt;                 /* Checkpoint sequence counter in the wal-header */
@@ -445,6 +436,13 @@ struct Wal {
 #define WAL_EXCLUSIVE_MODE  1     
 #define WAL_HEAPMEMORY_MODE 2
 
+/*
+** Possible values for WAL.readOnly
+*/
+#define WAL_RDWR        0    /* Normal read/write connection */
+#define WAL_RDONLY      1    /* The WAL file is readonly */
+#define WAL_SHM_RDONLY  2    /* The SHM file is readonly */
+
 /*
 ** Each page of the wal-index mapping contains a hash-table made up of
 ** an array of HASHTABLE_NSLOT elements of the following type.
@@ -538,23 +536,15 @@ static int walIndexPage(Wal *pWal, int iPage, volatile u32 **ppPage){
       rc = sqlite3OsShmMap(pWal->pDbFd, iPage, WALINDEX_PGSZ, 
           pWal->writeLock, (void volatile **)&pWal->apWiData[iPage]
       );
-      if( rc==SQLITE_CANTOPEN && pWal->readOnlyShm>1 ){
-        assert( iPage==0 );
-        sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_READONLY_SHM, (void*)1);
-        rc = sqlite3OsShmMap(pWal->pDbFd, iPage, WALINDEX_PGSZ, 
-            pWal->writeLock, (void volatile **)&pWal->apWiData[iPage]
-        );
-        if( rc==SQLITE_OK ){
-          pWal->readOnly = pWal->readOnlyShm = 1;
-        }
-        sqlite3OsFileControl(pWal->pDbFd, SQLITE_FCNTL_READONLY_SHM, (void*)0);
+      if( rc==SQLITE_READONLY ){
+        pWal->readOnly |= WAL_SHM_RDONLY;
+        rc = SQLITE_OK;
       }
     }
   }
-  *ppPage = pWal->apWiData[iPage];
 
+  *ppPage = pWal->apWiData[iPage];
   assert( iPage==0 || *ppPage || rc!=SQLITE_OK );
-  if( pWal->readOnlyShm>1 ) pWal->readOnlyShm = 0;
   return rc;
 }
 
@@ -794,7 +784,6 @@ static void walUnlockShared(Wal *pWal, int lockIdx){
 }
 static int walLockExclusive(Wal *pWal, int lockIdx, int n){
   int rc;
-  assert( pWal->readOnlyShm==0 );
   if( pWal->exclusiveMode ) return SQLITE_OK;
   rc = sqlite3OsShmLock(pWal->pDbFd, lockIdx, n,
                         SQLITE_SHM_LOCK | SQLITE_SHM_EXCLUSIVE);
@@ -804,7 +793,6 @@ static int walLockExclusive(Wal *pWal, int lockIdx, int n){
   return rc;
 }
 static void walUnlockExclusive(Wal *pWal, int lockIdx, int n){
-  assert( pWal->readOnlyShm==0 );
   if( pWal->exclusiveMode ) return;
   (void)sqlite3OsShmLock(pWal->pDbFd, lockIdx, n,
                          SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE);
@@ -1080,7 +1068,6 @@ static int walIndexRecover(Wal *pWal){
   assert( WAL_ALL_BUT_WRITE==WAL_WRITE_LOCK+1 );
   assert( WAL_CKPT_LOCK==WAL_ALL_BUT_WRITE );
   assert( pWal->writeLock );
-  assert( pWal->readOnlyShm==0 );
   iLock = WAL_ALL_BUT_WRITE + pWal->ckptLock;
   nLock = SQLITE_SHM_NLOCK - iLock;
   rc = walLockExclusive(pWal, iLock, nLock);
@@ -1300,7 +1287,7 @@ int sqlite3WalOpen(
   flags = (SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_WAL);
   rc = sqlite3OsOpen(pVfs, zWalName, pRet->pWalFd, flags, &flags);
   if( rc==SQLITE_OK && flags&SQLITE_OPEN_READONLY ){
-    pRet->readOnly = 1;
+    pRet->readOnly = WAL_RDONLY;
   }
 
   if( rc!=SQLITE_OK ){
@@ -1929,7 +1916,6 @@ static int walIndexReadHdr(Wal *pWal, int *pChanged){
     return rc;
   };
   assert( page0 || pWal->writeLock==0 );
-  assert( pWal->readOnlyShm==0 || pWal->readOnlyShm==1 );
 
   /* If the first page of the wal-index has been mapped, try to read the
   ** wal-index header immediately, without holding any lock. This usually
@@ -1939,11 +1925,11 @@ static int walIndexReadHdr(Wal *pWal, int *pChanged){
   badHdr = (page0 ? walIndexTryHdr(pWal, pChanged) : 1);
 
   /* If the first attempt failed, it might have been due to a race
-  ** with a writer. So lock the WAL_WRITE_LOCK byte and try again.
+  ** with a writer.  So get a WRITE lock and try again.
   */
   assert( badHdr==0 || pWal->writeLock==0 );
   if( badHdr ){
-    if( pWal->readOnlyShm ){
+    if( pWal->readOnly & WAL_SHM_RDONLY ){
       if( SQLITE_OK==(rc = walLockShared(pWal, WAL_WRITE_LOCK)) ){
         walUnlockShared(pWal, WAL_WRITE_LOCK);
         rc = SQLITE_READONLY_RECOVERY;
@@ -2150,7 +2136,9 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){
   }
   /* There was once an "if" here. The extra "{" is to preserve indentation. */
   {
-    if( pWal->readOnlyShm==0 && (mxReadMark < pWal->hdr.mxFrame || mxI==0) ){
+    if( (pWal->readOnly & WAL_SHM_RDONLY)==0
+     && (mxReadMark<pWal->hdr.mxFrame || mxI==0)
+    ){
       for(i=1; i<WAL_NREADER; i++){
         rc = walLockExclusive(pWal, WAL_READ_LOCK(i), 1);
         if( rc==SQLITE_OK ){
@@ -2165,7 +2153,6 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){
     }
     if( mxI==0 ){
       assert( rc==SQLITE_BUSY );
-      assert( rc==SQLITE_BUSY || (pWal->readOnlyShm && rc==SQLITE_OK) );
       return rc==SQLITE_BUSY ? WAL_RETRY : SQLITE_READONLY_CANTLOCK;
     }
 
@@ -2221,18 +2208,13 @@ static int walTryBeginRead(Wal *pWal, int *pChanged, int useWal, int cnt){
 ** Pager layer will use this to know that is cache is stale and
 ** needs to be flushed.
 */
-int sqlite3WalBeginReadTransaction(Wal *pWal, int readOnlyShm, int *pChanged){
+int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){
   int rc;                         /* Return code */
   int cnt = 0;                    /* Number of TryBeginRead attempts */
 
-  if( pWal->nWiData==0 || pWal->apWiData[0]==0 ){
-    assert( readOnlyShm==0 || readOnlyShm==1 );
-    pWal->readOnlyShm = readOnlyShm*2;
-  }
   do{
     rc = walTryBeginRead(pWal, pChanged, 0, ++cnt);
   }while( rc==WAL_RETRY );
-  assert( rc || pWal->readOnlyShm==0 || (readOnlyShm && pWal->readOnlyShm==1) );
   testcase( (rc&0xff)==SQLITE_BUSY );
   testcase( (rc&0xff)==SQLITE_IOERR );
   testcase( rc==SQLITE_PROTOCOL );
@@ -2407,7 +2389,6 @@ int sqlite3WalBeginWriteTransaction(Wal *pWal){
   if( pWal->readOnly ){
     return SQLITE_READONLY;
   }
-  assert( pWal->readOnlyShm==0 );
 
   /* Only one writer allowed at a time.  Get the write lock.  Return
   ** SQLITE_BUSY if unable.
@@ -2814,11 +2795,8 @@ int sqlite3WalCheckpoint(
   assert( pWal->ckptLock==0 );
   assert( pWal->writeLock==0 );
 
+  if( pWal->readOnly ) return SQLITE_READONLY;
   WALTRACE(("WAL%p: checkpoint begins\n", pWal));
-  if( pWal->readOnlyShm ){
-    return SQLITE_READONLY;
-  }
-
   rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1);
   if( rc ){
     /* Usually this is SQLITE_BUSY meaning that another thread or process
index df09beffe7db34cd88b4d7c8862206d1409d2c03..a62b23bbdc99f2551bcb8f8083541b0968113478 100644 (file)
--- a/src/wal.h
+++ b/src/wal.h
@@ -23,7 +23,7 @@
 # define sqlite3WalOpen(x,y,z)                   0
 # define sqlite3WalLimit(x,y)
 # define sqlite3WalClose(w,x,y,z)                0
-# define sqlite3WalBeginReadTransaction(x,y,z)   0
+# define sqlite3WalBeginReadTransaction(y,z)     0
 # define sqlite3WalEndReadTransaction(z)
 # define sqlite3WalRead(v,w,x,y,z)               0
 # define sqlite3WalDbsize(y)                     0
@@ -60,7 +60,7 @@ void sqlite3WalLimit(Wal*, i64);
 ** write to or checkpoint the WAL.  sqlite3WalCloseSnapshot() closes the
 ** transaction and releases the lock.
 */
-int sqlite3WalBeginReadTransaction(Wal *pWal, int, int *);
+int sqlite3WalBeginReadTransaction(Wal *pWal, int *);
 void sqlite3WalEndReadTransaction(Wal *pWal);
 
 /* Read a page from the write-ahead log, if it is present. */