Change the semantics of xShmGet() such that it will never increase the size
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
This commit is contained in:
parent
51b21b169a
commit
026ac28b28
22
manifest
22
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-----
|
||||
|
@ -1 +1 @@
|
||||
687632a6b3a0aeb006c1eda5c27d5489f08c230e
|
||||
72de00731245277b2209103ec0a76e3d4f56530e
|
@ -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;
|
||||
|
17
src/os_win.c
17
src/os_win.c
@ -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 */
|
||||
|
48
src/wal.c
48
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))
|
||||
){
|
||||
|
Loading…
Reference in New Issue
Block a user