diff options
author | drh <drh@noemail.net> | 2010-05-26 15:06:38 +0000 |
---|---|---|
committer | drh <drh@noemail.net> | 2010-05-26 15:06:38 +0000 |
commit | 026ac28b283c040539a3e2bca0ce608e0fe31a04 (patch) | |
tree | 0c6a4840cb4d228490627ccb36ae33cd9bb9adf2 /src/os_unix.c | |
parent | 51b21b169ac0336e69ee9f8f95f3ac18ef97a567 (diff) | |
download | sqlite-026ac28b283c040539a3e2bca0ce608e0fe31a04.tar.gz sqlite-026ac28b283c040539a3e2bca0ce608e0fe31a04.zip |
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
Diffstat (limited to 'src/os_unix.c')
-rw-r--r-- | src/os_unix.c | 60 |
1 files changed, 29 insertions, 31 deletions
diff --git a/src/os_unix.c b/src/os_unix.c index 48f4d3884..227a3c518 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 - && 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; |