diff --git a/manifest b/manifest index 9f66cbf293..c5c5d4f7fb 100644 --- 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----- diff --git a/manifest.uuid b/manifest.uuid index 53450f9eb9..26655fd897 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -687632a6b3a0aeb006c1eda5c27d5489f08c230e \ No newline at end of file +72de00731245277b2209103ec0a76e3d4f56530e \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index 48f4d38847..227a3c5181 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -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 - && reqMapSizepMMapBuf ){ + 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; diff --git a/src/os_win.c b/src/os_win.c index 7f1b5ebb12..fdcdda85f1 100644 --- a/src/os_win.c +++ b/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 */ diff --git a/src/wal.c b/src/wal.c index 1f983edccf..cd27449ac5 100644 --- 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)) ){