aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2010-05-13 08:33:35 +0000
committerdrh <drh@noemail.net>2010-05-13 08:33:35 +0000
commita925fd256b74e5da9c6320849c3b7d85110ce73f (patch)
tree7a5fa6c0dfea4d2935f28261fc38430f0385b0e1 /src
parentbd50ddeb42ac99c98c65beca62f29f0e1c0a97e3 (diff)
downloadsqlite-a925fd256b74e5da9c6320849c3b7d85110ce73f.tar.gz
sqlite-a925fd256b74e5da9c6320849c3b7d85110ce73f.zip
Change the xShmSize() implementation in os_unix.c so that it will only
increase and never decrease the size of a shared-memory segment. FossilOrigin-Name: 149d2ae4a6fe2f86822f286d2a7092c51bec7ebb
Diffstat (limited to 'src')
-rw-r--r--src/os_unix.c23
1 files changed, 16 insertions, 7 deletions
diff --git a/src/os_unix.c b/src/os_unix.c
index ff967ca8b..4ddff190a 100644
--- a/src/os_unix.c
+++ b/src/os_unix.c
@@ -3957,16 +3957,25 @@ static int unixShmSize(
int rc = SQLITE_OK;
struct stat sStat;
- if( reqSize>=0 ){
+ /* 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(pFile->h, &sStat)==0 ){
+ *pNewSize = (int)sStat.st_size;
+ if( reqSize>=0 && 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(pFile->h, reqSize);
- }
- if( fstat(pFile->h, &sStat)==0 ){
- *pNewSize = (int)sStat.st_size;
- }else{
- *pNewSize = 0;
- rc = SQLITE_IOERR;
+ reqSize = -1;
}
return rc;
}