]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Change the semantics of xShmGet() such that it will never increase the size
authordrh <drh@noemail.net>
Wed, 26 May 2010 15:06:38 +0000 (15:06 +0000)
committerdrh <drh@noemail.net>
Wed, 26 May 2010 15:06:38 +0000 (15:06 +0000)
of shared memory.  xShmSize() must be used to grow the size of shared memory.
A shared memory segment size cannot be shrunk (except by dropping it).

FossilOrigin-Name: 72de00731245277b2209103ec0a76e3d4f56530e

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

index 9f66cbf29358b3e2fa55763e972eae8bcb0fa319..c5c5d4f7fb882d97d29537f695f67c267daeaaf4 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,8 +1,8 @@
 -----BEGIN PGP SIGNED MESSAGE-----
 Hash: SHA1
 
-C Updated\sheader\scomments\sin\swal.c.\s\sNo\sfunctional\scode\schanges.
-D 2010-05-25T15:53:32
+C Change\sthe\ssemantics\sof\sxShmGet()\ssuch\sthat\sit\swill\snever\sincrease\sthe\ssize\nof\sshared\smemory.\s\sxShmSize()\smust\sbe\sused\sto\sgrow\sthe\ssize\sof\sshared\smemory.\nA\sshared\smemory\ssegment\ssize\scannot\sbe\sshrunk\s(except\sby\sdropping\sit).
+D 2010-05-26T15:06:38
 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
 F Makefile.in a5cad1f8f3e021356bfcc6c77dc16f6f1952bbc3
 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
@@ -155,8 +155,8 @@ F src/os.c 2285265f7e8035ba77e8e8ec93adf3c3c61fc60e
 F src/os.h efcc7f0072ae362b44eab8588b43a943da61504e
 F src/os_common.h a8f95b81eca8a1ab8593d23e94f8a35f35d4078f
 F src/os_os2.c 665876d5eec7585226b0a1cf5e18098de2b2da19
-F src/os_unix.c a5771c3fcf78d0f2f5f547accff662c9bda8a32e
-F src/os_win.c e300c8f85c1be853f977e50f9292e61a396e6a33
+F src/os_unix.c 683ba91de68419771b13f2b9a3dc0e439147e199
+F src/os_win.c 81dd8f5434b3b73b1f1567a784811601b6437ce3
 F src/pager.c 5d693cc6273c5406a21f1a2afa18309457273549
 F src/pager.h 76466c3a5af56943537f68b1f16567101a0cd1d0
 F src/parse.y ace5c7a125d9f2a410e431ee3209034105045f7e
@@ -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 910ec66f5ecaa5ddf11c2d621c41402c585844ad
+F src/wal.c 603f6ad6fa9a1ff400042a2aafe26ade7a2460a9
 F src/wal.h 111c6f3efd83fe2fc707b29e26431e8eff4c6f28
 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 d3d348aa975c58c37088eb2830081880896b85e7
-R 0260887750a4ff2568ebba7befa4c293
+P 687632a6b3a0aeb006c1eda5c27d5489f08c230e
+R 10265da0d50a2ddb803b6a733956f1ed
 U drh
-Z b37d90009a6b0e9be74143cbddd6561b
+Z 8953a9a318d02ec6ed8374658e58a902
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.4.6 (GNU/Linux)
 
-iD8DBQFL+/J+oxKgR168RlERAs9wAJwJ+gskjCIcTQjaf9yUnO8hh8VQAACgjW95
-h2OPmMbpiQ7QHTW3OKLS5Hc=
-=mxeE
+iD8DBQFL/TkBoxKgR168RlERAviGAJ4+8lzL8Zi3Jko72hinaOLrZV5mAgCePzCx
+pZpI8grIC+ipxJIOxg4scYk=
+=Hslv
 -----END PGP SIGNATURE-----
index 53450f9eb9735d89c2021f6d956dcb669b8eee69..26655fd897ba7f9ea2813bb2360713eac6be8981 100644 (file)
@@ -1 +1 @@
-687632a6b3a0aeb006c1eda5c27d5489f08c230e
\ No newline at end of file
+72de00731245277b2209103ec0a76e3d4f56530e
\ No newline at end of file
index 48f4d3884754600006b77aeb8dfff715fba49aab..227a3c51819a63cd41cd72244661d850e3d1c0ef 100644 (file)
@@ -3602,15 +3602,12 @@ static int unixShmClose(
 }
 
 /*
-** Query and/or changes the size of the underlying storage for
-** a shared-memory segment.  The reqSize parameter is the new size
-** of the underlying storage, or -1 to do just a query.  The size
-** of the underlying storage (after resizing if resizing occurs) is
-** written into pNewSize.
+** Changes the size of the underlying storage for  a shared-memory segment.
 **
-** This routine does not (necessarily) change the size of the mapping 
-** of the underlying storage into memory.  Use xShmGet() to change
-** the mapping size.
+** The reqSize parameter is the new requested size of the shared memory.
+** This implementation is free to increase the shared memory size to
+** any amount greater than or equal to reqSize.  If the shared memory is
+** already as big or bigger as reqSize, this routine is a no-op.
 **
 ** The reqSize parameter is the minimum size requested.  The implementation
 ** is free to expand the storage to some larger amount if it chooses.
@@ -3629,23 +3626,15 @@ static int unixShmSize(
   assert( pShmNode==pDbFd->pInode->pShmNode );
   assert( pShmNode->pInode==pDbFd->pInode );
 
-  /* On a query, this loop runs once.  When reqSize>=0, the loop potentially
-  ** runs twice, except if the actual size is already greater than or equal
-  ** to the requested size, reqSize is set to -1 on the first iteration and
-  ** the loop only runs once.
-  */
   while( 1 ){
     if( fstat(pShmNode->h, &sStat)==0 ){
       *pNewSize = (int)sStat.st_size;
-      if( reqSize>=0 && reqSize<=(int)sStat.st_size ) break;
+      if( reqSize<=(int)sStat.st_size ) break;
     }else{
       *pNewSize = 0;
       rc = SQLITE_IOERR;
       break;
     }
-    if( reqSize<0 ) break;
-    reqSize = (reqSize + SQLITE_UNIX_SHM_INCR - 1)/SQLITE_UNIX_SHM_INCR;
-    reqSize *= SQLITE_UNIX_SHM_INCR;
     rc = ftruncate(pShmNode->h, reqSize);
     reqSize = -1;
   }
@@ -3654,10 +3643,12 @@ static int unixShmSize(
 
 
 /*
-** Map the shared storage into memory.  The minimum size of the
-** mapping should be reqMapSize if reqMapSize is positive.  If
-** reqMapSize is zero or negative, the implementation can choose
-** whatever mapping size is convenient.
+** Map the shared storage into memory. 
+**
+** If reqMapSize is positive, then an attempt is made to make the
+** mapping at least reqMapSize bytes in size.  However, the mapping
+** will never be larger than the size of the underlying shared memory
+** as set by prior calls to xShmSize().  
 **
 ** *ppBuf is made to point to the memory which is a mapping of the
 ** underlying storage.  A mutex is acquired to prevent other threads
@@ -3674,9 +3665,12 @@ static int unixShmSize(
 ** To prevent RECOVER from losing its lock while remapping, the
 ** mutex is not released by unixShmRelease() when in RECOVER.
 **
-** *pNewMapSize is set to the size of the mapping.
+** *pNewMapSize is set to the size of the mapping.  Usually *pNewMapSize
+** will be reqMapSize or larger, though it could be smaller if the
+** underlying shared memory has never been enlarged to reqMapSize bytes
+** by prior calls to xShmSize().
 **
-** *ppBuf and *pNewMapSize might be NULL and zero if no space has
+** *ppBuf might be NULL and zero if no space has
 ** yet been allocated to the underlying storage.
 */
 static int unixShmGet(
@@ -3701,17 +3695,21 @@ static int unixShmGet(
   sqlite3_mutex_enter(pShmNode->mutex);
   if( pShmNode->szMap==0 || reqMapSize>pShmNode->szMap ){
     int actualSize;
-    if( unixShmSize(fd, -1, &actualSize)==SQLITE_OK
-     && reqMapSize<actualSize
-    ){
-      reqMapSize = actualSize;
+    if( unixShmSize(fd, -1, &actualSize)!=SQLITE_OK ){
+      actualSize = 0;
     }
-    if( pShmNode->pMMapBuf ){
+    reqMapSize = actualSize;
+    if( pShmNode->pMMapBuf || reqMapSize<=0 ){
       munmap(pShmNode->pMMapBuf, pShmNode->szMap);
     }
-    pShmNode->pMMapBuf = mmap(0, reqMapSize, PROT_READ|PROT_WRITE, MAP_SHARED,
-                           pShmNode->h, 0);
-    pShmNode->szMap = pShmNode->pMMapBuf ? reqMapSize : 0;
+    if( reqMapSize>0 ){
+      pShmNode->pMMapBuf = mmap(0, reqMapSize, PROT_READ|PROT_WRITE, MAP_SHARED,
+                             pShmNode->h, 0);
+      pShmNode->szMap = pShmNode->pMMapBuf ? reqMapSize : 0;
+    }else{
+      pShmNode->pMMapBuf = 0;
+      pShmNode->szMap = 0;
+    }
   }
   *pNewMapSize = pShmNode->szMap;
   *ppBuf = pShmNode->pMMapBuf;
index 7f1b5ebb12058d6e8d696add3d6b7f52d93f2256..fdcdda85f1f19b7f7e557c74d571efbe50293a6a 100644 (file)
@@ -1758,18 +1758,15 @@ static int winShmClose(
 }
 
 /*
-** Query and/or changes the size of the underlying storage for
-** a shared-memory segment.  The reqSize parameter is the new size
-** of the underlying storage, or -1 to do just a query.  The size
-** of the underlying storage (after resizing if resizing occurs) is
-** written into pNewSize.
+** Increase the size of the underlying storage for a shared-memory segment.
 **
-** This routine does not (necessarily) change the size of the mapping 
-** of the underlying storage into memory.  Use xShmGet() to change
-** the mapping size.
+** The reqSize parameter is the new requested minimum size of the underlying
+** shared memory.  This routine may choose to make the shared memory larger
+** than this value (for example to round the shared memory size up to an
+** operating-system dependent page size.)
 **
-** The reqSize parameter is the minimum size requested.  The implementation
-** is free to expand the storage to some larger amount if it chooses.
+** This routine will only grow the size of shared memory.  A request for
+** a smaller size is a no-op.
 */
 static int winShmSize(
   sqlite3_file *fd,         /* Database holding the shared memory */
index 1f983edccf40098b3dede44c5b141b7647f7da6e..cd27449ac5400abfbeaa5eedddce6a3b95b0ee75 100644 (file)
--- a/src/wal.c
+++ b/src/wal.c
@@ -244,6 +244,7 @@ struct WalIndexHdr {
 */
 #define WALINDEX_LOCK_OFFSET   (sizeof(WalIndexHdr)*2)
 #define WALINDEX_LOCK_RESERVED 8
+#define WALINDEX_HDR_SIZE      (WALINDEX_LOCK_OFFSET+WALINDEX_LOCK_RESERVED)
 
 /* Size of header before each frame in wal */
 #define WAL_FRAME_HDRSIZE 24
@@ -562,15 +563,18 @@ static int walMappingSize(u32 iFrame){
 static void walIndexUnmap(Wal *pWal){
   if( pWal->pWiData ){
     sqlite3OsShmRelease(pWal->pDbFd);
-    pWal->pWiData = 0;
   }
+  pWal->pWiData = 0;
+  pWal->szWIndex = -1;
 }
 
 /*
 ** Map the wal-index file into memory if it isn't already. 
 **
-** The reqSize parameter is the minimum required size of the mapping.
-** A value of -1 means "don't care".
+** The reqSize parameter is the requested size of the mapping.  The
+** mapping will be at least this big if the underlying storage is
+** that big.  But the mapping will never grow larger than the underlying
+** storage.  Use the walIndexRemap() to enlarget the storage space.
 */
 static int walIndexMap(Wal *pWal, int reqSize){
   int rc = SQLITE_OK;
@@ -578,12 +582,6 @@ static int walIndexMap(Wal *pWal, int reqSize){
     walIndexUnmap(pWal);
     rc = sqlite3OsShmGet(pWal->pDbFd, reqSize, &pWal->szWIndex,
                              (void volatile**)(char volatile*)&pWal->pWiData);
-    if( rc==SQLITE_OK && pWal->pWiData==0 ){
-      /* Make sure pWal->pWiData is not NULL while we are holding the
-      ** lock on the mapping. */
-      assert( pWal->szWIndex==0 );
-      pWal->pWiData = &pWal->iCallback;
-    }
     if( rc!=SQLITE_OK ){
       walIndexUnmap(pWal);
     }
@@ -592,6 +590,7 @@ static int walIndexMap(Wal *pWal, int reqSize){
 }
 
 /*
+** Enlarge the wal-index to be at least enlargeTo bytes in size and
 ** Remap the wal-index so that the mapping covers the full size
 ** of the underlying file.
 **
@@ -601,20 +600,16 @@ static int walIndexMap(Wal *pWal, int reqSize){
 static int walIndexRemap(Wal *pWal, int enlargeTo){
   int rc;
   int sz;
+  assert( pWal->lockState>=SQLITE_SHM_WRITE );
   rc = sqlite3OsShmSize(pWal->pDbFd, enlargeTo, &sz);
   if( rc==SQLITE_OK && sz>pWal->szWIndex ){
     walIndexUnmap(pWal);
     rc = walIndexMap(pWal, sz);
   }
+  assert( pWal->szWIndex>=enlargeTo || rc!=SQLITE_OK );
   return rc;
 }
 
-/*
-** Increment by which to increase the wal-index file size.
-*/
-#define WALINDEX_MMAP_INCREMENT (64*1024)
-
-
 /*
 ** Compute a hash on a page number.  The resulting hash value must land
 ** between 0 and (HASHTABLE_NSLOT-1).
@@ -738,10 +733,9 @@ static int walIndexAppend(Wal *pWal, u32 iFrame, u32 iPage){
   
   /* Make sure the wal-index is mapped. Enlarge the mapping if required. */
   nMapping = walMappingSize(iFrame);
-  rc = walIndexMap(pWal, -1);
+  rc = walIndexMap(pWal, nMapping);
   while( rc==SQLITE_OK && nMapping>pWal->szWIndex ){
-    int nByte = pWal->szWIndex + WALINDEX_MMAP_INCREMENT;
-    rc = walIndexRemap(pWal, nByte);
+    rc = walIndexRemap(pWal, nMapping);
   }
 
   /* Assuming the wal-index file was successfully mapped, find the hash 
@@ -907,7 +901,7 @@ static int walIndexRecover(Wal *pWal){
 
 finished:
   if( rc==SQLITE_OK && pWal->hdr.mxFrame==0 ){
-    rc = walIndexRemap(pWal, WALINDEX_MMAP_INCREMENT);
+    rc = walIndexRemap(pWal, walMappingSize(1));
   }
   if( rc==SQLITE_OK ){
     pWal->hdr.aFrameCksum[0] = aFrameCksum[0];
@@ -983,6 +977,7 @@ int sqlite3WalOpen(
   pRet->pVfs = pVfs;
   pRet->pWalFd = (sqlite3_file *)&pRet[1];
   pRet->pDbFd = pDbFd;
+  pRet->szWIndex = -1;
   sqlite3_randomness(8, &pRet->hdr.aSalt);
   pRet->zWalName = zWal = pVfs->szOsFile + (char*)pRet->pWalFd;
   sqlite3_snprintf(nWal, zWal, "%s-wal", zDbName);
@@ -1309,14 +1304,12 @@ int walIndexTryHdr(Wal *pWal, int *pChanged){
   WalIndexHdr h1, h2;          /* Two copies of the header content */
   WalIndexHdr *aHdr;           /* Header in shared memory */
 
-  assert( pWal->pWiData );
-  if( pWal->szWIndex==0 ){
-    /* The wal-index is of size 0 bytes. This is handled in the same way
-    ** as an invalid header. The caller will run recovery to construct
-    ** a valid wal-index file before accessing the database.
-    */
+  if( pWal->szWIndex < WALINDEX_HDR_SIZE ){
+    /* The wal-index is not large enough to hold the header, then assume
+    ** header is invalid. */
     return 1;
   }
+  assert( pWal->pWiData );
 
   /* Read the header. The caller may or may not have an exclusive 
   ** (WRITE, PENDING, CHECKPOINT or RECOVER) lock on the wal-index
@@ -1378,7 +1371,7 @@ static int walIndexReadHdr(Wal *pWal, int *pChanged){
 
   assert( pWal->lockState>=SQLITE_SHM_READ );
   assert( pChanged );
-  rc = walIndexMap(pWal, -1);
+  rc = walIndexMap(pWal, walMappingSize(1));
   if( rc!=SQLITE_OK ){
     return rc;
   }
@@ -1628,7 +1621,8 @@ int sqlite3WalWriteLock(Wal *pWal, int op){
     ** the write locks and return SQLITE_BUSY.
     */
     if( rc==SQLITE_OK ){
-      rc = walIndexMap(pWal, sizeof(WalIndexHdr));
+      rc = walIndexMap(pWal, walMappingSize(1));
+      assert( pWal->szWIndex>=WALINDEX_HDR_SIZE || rc!=SQLITE_OK );
       if( rc==SQLITE_OK
        && memcmp(&pWal->hdr, (void*)pWal->pWiData, sizeof(WalIndexHdr))
       ){