From: drh Date: Sat, 12 Mar 2011 18:10:44 +0000 (+0000) Subject: In the "unix-excl" VFS, use the heap for shared memory, since only a single X-Git-Tag: version-3.7.6~103^2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=refs%2Fheads%2Funix-excl;p=thirdparty%2Fsqlite.git In the "unix-excl" VFS, use the heap for shared memory, since only a single process is able to read or write the database. FossilOrigin-Name: a05a6d40875df674f9c2b46e33128c6878d4edaa --- diff --git a/manifest b/manifest index 014dfe961b..053cef99a8 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 -C Add\sthe\snew\soptional\s"unix-excl"\sVFS.\s\sThis\sVFS\sgrabs\san\sexclusive\slock\son\nthe\sdatabase\spreventing\sother\sprocesses\sfrom\saccessing\sit,\sbut\scontinues\sto\nallow\sother\sdatabase\sconnections\sfrom\sthe\ssame\sprocess. -D 2011-03-12T17:02:57.101 +C In\sthe\s"unix-excl"\sVFS,\suse\sthe\sheap\sfor\sshared\smemory,\ssince\sonly\sa\ssingle\nprocess\sis\sable\sto\sread\sor\swrite\sthe\sdatabase. +D 2011-03-12T18:10:44.973 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -165,7 +165,7 @@ F src/os.c 22ac61d06e72a0dac900400147333b07b13d8e1d F src/os.h 9dbed8c2b9c1f2f2ebabc09e49829d4777c26bf9 F src/os_common.h a8f95b81eca8a1ab8593d23e94f8a35f35d4078f F src/os_os2.c 2596fd2d5d0976c6c0c628d0c3c7c4e7a724f4cf -F src/os_unix.c 557837beff775c448bb072ae21edeff912d1f0df +F src/os_unix.c 1debf5ea6efd0f35335a2a615198a7a1017ffd4b F src/os_win.c 24d72407a90551969744cf9bcbb1b4c72c5fa845 F src/pager.c 6aa906b60a59664ba58d3f746164bb010d407ce1 F src/pager.h 3f8c783de1d4706b40b1ac15b64f5f896bcc78d1 @@ -916,18 +916,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P b86999436ec2414c990ba720441fe316f647eef6 -R b4018b4a3ca8304164ff6618b813c5a9 -T *bgcolor * #aaa8d3 -T *branch * unix-excl -T *sym-unix-excl * -T -sym-trunk * +P 00051c3296e11211b2bb5ae28f016b17dca857d7 +R ae21c3eefa2912bdd40576825c99670e U drh -Z ca346ade739e93ef182345e803581a80 +Z 0353c9261ee94db4155a765014c19a0b -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) -iD8DBQFNe6dEoxKgR168RlERAkgMAJ47rTo3YzDvLp8S+pIflXBmm5FOSwCggCkn -s82X2XcH9cqBqUU6lQenClw= -=LUbU +iD8DBQFNe7cnoxKgR168RlERAsDBAJ486IVhWF+3w87MQdsa9IV6+Kk3UQCfVQ5D +gOLo9IyLtbi3pQ3LQfZd9Y8= +=wzQK -----END PGP SIGNATURE----- diff --git a/manifest.uuid b/manifest.uuid index e7ce79f84b..178e5215aa 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -00051c3296e11211b2bb5ae28f016b17dca857d7 \ No newline at end of file +a05a6d40875df674f9c2b46e33128c6878d4edaa \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index c373ebee6b..246a2d5776 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -1202,17 +1202,21 @@ static int unixCheckReservedLock(sqlite3_file *id, int *pResOut){ */ static int unixFileLock(unixFile *pFile, struct flock *pLock){ int rc; + unixInodeInfo *pInode = pFile->pInode; assert( unixMutexHeld() ); - if( (pFile->ctrlFlags & UNIXFILE_EXCL)!=0 || pFile->pInode->bProcessLock ){ - if( pFile->pInode->bProcessLock==0 ){ + assert( pInode!=0 ); + if( (pFile->ctrlFlags & UNIXFILE_EXCL)!=0 || pInode->bProcessLock ){ + if( pInode->bProcessLock==0 ){ struct flock lock; + assert( pInode->nLock==0 ); lock.l_whence = SEEK_SET; lock.l_start = SHARED_FIRST; lock.l_len = SHARED_SIZE; lock.l_type = F_WRLCK; rc = osFcntl(pFile->h, F_SETLK, &lock); if( rc<0 ) return rc; - pFile->pInode->bProcessLock = 1; + pInode->bProcessLock = 1; + pInode->nLock++; }else{ rc = 0; } @@ -1731,6 +1735,8 @@ static int unixClose(sqlite3_file *id){ unixFile *pFile = (unixFile *)id; unixUnlock(id, NO_LOCK); unixEnterMutex(); + assert( pFile->pInode==0 || pFile->pInode->nLock>0 + || pFile->pInode->bProcessLock==0 ); if( pFile->pInode && pFile->pInode->nLock ){ /* If there are outstanding locks, do not actually close the file just ** yet because that would clear those locks. Instead, add the file @@ -3559,15 +3565,17 @@ static int unixShmSystemLock( /* Locks are within range */ assert( n>=1 && nh>=0 ){ + /* Initialize the locking parameters */ + memset(&f, 0, sizeof(f)); + f.l_type = lockType; + f.l_whence = SEEK_SET; + f.l_start = ofst; + f.l_len = n; - rc = osFcntl(pShmNode->h, F_SETLK, &f); - rc = (rc!=(-1)) ? SQLITE_OK : SQLITE_BUSY; + rc = osFcntl(pShmNode->h, F_SETLK, &f); + rc = (rc!=(-1)) ? SQLITE_OK : SQLITE_BUSY; + } /* Update the global lock state and do debug tracing */ #ifdef SQLITE_DEBUG @@ -3622,7 +3630,11 @@ static void unixShmPurge(unixFile *pFd){ assert( p->pInode==pFd->pInode ); if( p->mutex ) sqlite3_mutex_free(p->mutex); for(i=0; inRegion; i++){ - munmap(p->apRegion[i], p->szRegion); + if( p->h>=0 ){ + munmap(p->apRegion[i], p->szRegion); + }else{ + sqlite3_free(p->apRegion[i]); + } } sqlite3_free(p->apRegion); if( p->h>=0 ){ @@ -3662,6 +3674,12 @@ static void unixShmPurge(unixFile *pFd){ ** When opening a new shared-memory file, if no other instances of that ** file are currently open, in this process or in other processes, then ** the file must be truncated to zero length or have its header cleared. +** +** If the original database file (pDbFd) is using the "unix-excl" VFS +** that means that an exclusive lock is held on the database file and +** that no other processes are able to read or write the database. In +** that case, we do not really need shared memory. No shared memory +** file is created. The shared memory will be simulated with heap memory. */ static int unixOpenSharedMemory(unixFile *pDbFd){ struct unixShm *p = 0; /* The connection to be opened */ @@ -3691,7 +3709,7 @@ static int unixOpenSharedMemory(unixFile *pDbFd){ ** with the same permissions. The actual permissions the file is created ** with are subject to the current umask setting. */ - if( osFstat(pDbFd->h, &sStat) ){ + if( osFstat(pDbFd->h, &sStat) && pInode->bProcessLock==0 ){ rc = SQLITE_IOERR_FSTAT; goto shm_open_err; } @@ -3724,26 +3742,28 @@ static int unixOpenSharedMemory(unixFile *pDbFd){ goto shm_open_err; } - pShmNode->h = robust_open(zShmFilename, O_RDWR|O_CREAT, - (sStat.st_mode & 0777)); - if( pShmNode->h<0 ){ - rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShmFilename); - goto shm_open_err; - } - - /* Check to see if another process is holding the dead-man switch. - ** If not, truncate the file to zero length. - */ - rc = SQLITE_OK; - if( unixShmSystemLock(pShmNode, F_WRLCK, UNIX_SHM_DMS, 1)==SQLITE_OK ){ - if( robust_ftruncate(pShmNode->h, 0) ){ - rc = unixLogError(SQLITE_IOERR_SHMOPEN, "ftruncate", zShmFilename); + if( pInode->bProcessLock==0 ){ + pShmNode->h = robust_open(zShmFilename, O_RDWR|O_CREAT, + (sStat.st_mode & 0777)); + if( pShmNode->h<0 ){ + rc = unixLogError(SQLITE_CANTOPEN_BKPT, "open", zShmFilename); + goto shm_open_err; } + + /* Check to see if another process is holding the dead-man switch. + ** If not, truncate the file to zero length. + */ + rc = SQLITE_OK; + if( unixShmSystemLock(pShmNode, F_WRLCK, UNIX_SHM_DMS, 1)==SQLITE_OK ){ + if( robust_ftruncate(pShmNode->h, 0) ){ + rc = unixLogError(SQLITE_IOERR_SHMOPEN, "ftruncate", zShmFilename); + } + } + if( rc==SQLITE_OK ){ + rc = unixShmSystemLock(pShmNode, F_RDLCK, UNIX_SHM_DMS, 1); + } + if( rc ) goto shm_open_err; } - if( rc==SQLITE_OK ){ - rc = unixShmSystemLock(pShmNode, F_RDLCK, UNIX_SHM_DMS, 1); - } - if( rc ) goto shm_open_err; } /* Make the new connection a child of the unixShmNode */ @@ -3817,6 +3837,9 @@ static int unixShmMap( pShmNode = p->pShmNode; sqlite3_mutex_enter(pShmNode->mutex); assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 ); + assert( pShmNode->pInode==pDbFd->pInode ); + assert( pShmNode->h>=0 || pDbFd->pInode->bProcessLock==1 ); + assert( pShmNode->h<0 || pDbFd->pInode->bProcessLock==0 ); if( pShmNode->nRegion<=iRegion ){ char **apNew; /* New apRegion[] array */ @@ -3825,27 +3848,30 @@ static int unixShmMap( pShmNode->szRegion = szRegion; - /* The requested region is not mapped into this processes address space. - ** Check to see if it has been allocated (i.e. if the wal-index file is - ** large enough to contain the requested region). - */ - if( osFstat(pShmNode->h, &sStat) ){ - rc = SQLITE_IOERR_SHMSIZE; - goto shmpage_out; - } - - if( sStat.st_sizeh>=0 ){ + /* The requested region is not mapped into this processes address space. + ** Check to see if it has been allocated (i.e. if the wal-index file is + ** large enough to contain the requested region). */ - if( !bExtend ) goto shmpage_out; - if( robust_ftruncate(pShmNode->h, nByte) ){ - rc = unixLogError(SQLITE_IOERR_SHMSIZE,"ftruncate",pShmNode->zFilename); + if( osFstat(pShmNode->h, &sStat) ){ + rc = SQLITE_IOERR_SHMSIZE; goto shmpage_out; } + + if( sStat.st_sizeh, nByte) ){ + rc = unixLogError(SQLITE_IOERR_SHMSIZE, "ftruncate", + pShmNode->zFilename); + goto shmpage_out; + } + } } /* Map the requested memory region into this processes address space. */ @@ -3858,12 +3884,22 @@ static int unixShmMap( } pShmNode->apRegion = apNew; while(pShmNode->nRegion<=iRegion){ - void *pMem = mmap(0, szRegion, PROT_READ|PROT_WRITE, - MAP_SHARED, pShmNode->h, pShmNode->nRegion*szRegion - ); - if( pMem==MAP_FAILED ){ - rc = SQLITE_IOERR; - goto shmpage_out; + void *pMem; + if( pShmNode->h>=0 ){ + pMem = mmap(0, szRegion, PROT_READ|PROT_WRITE, + MAP_SHARED, pShmNode->h, pShmNode->nRegion*szRegion + ); + if( pMem==MAP_FAILED ){ + rc = SQLITE_IOERR; + goto shmpage_out; + } + }else{ + pMem = sqlite3_malloc(szRegion); + if( pMem==0 ){ + rc = SQLITE_NOMEM; + goto shmpage_out; + } + memset(pMem, 0, szRegion); } pShmNode->apRegion[pShmNode->nRegion] = pMem; pShmNode->nRegion++; @@ -3910,6 +3946,8 @@ static int unixShmLock( || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED) || flags==(SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE) ); assert( n==1 || (flags & SQLITE_SHM_EXCLUSIVE)!=0 ); + assert( pShmNode->h>=0 || pDbFd->pInode->bProcessLock==1 ); + assert( pShmNode->h<0 || pDbFd->pInode->bProcessLock==0 ); mask = (1<<(ofst+n)) - (1<1 || mask==(1<nRef>0 ); pShmNode->nRef--; if( pShmNode->nRef==0 ){ - if( deleteFlag ) unlink(pShmNode->zFilename); + if( deleteFlag && pShmNode->h>=0 ) unlink(pShmNode->zFilename); unixShmPurge(pDbFd); } unixLeaveMutex();