-----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
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
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
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-----
-687632a6b3a0aeb006c1eda5c27d5489f08c230e
\ No newline at end of file
+72de00731245277b2209103ec0a76e3d4f56530e
\ No newline at end of file
}
/*
-** 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.
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;
}
/*
-** 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
** 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(
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;
}
/*
-** 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 */
*/
#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
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;
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);
}
}
/*
+** 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.
**
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).
/* 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
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];
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);
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
assert( pWal->lockState>=SQLITE_SHM_READ );
assert( pChanged );
- rc = walIndexMap(pWal, -1);
+ rc = walIndexMap(pWal, walMappingSize(1));
if( rc!=SQLITE_OK ){
return rc;
}
** 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))
){