diff options
author | dan <dan@noemail.net> | 2010-06-14 14:07:50 +0000 |
---|---|---|
committer | dan <dan@noemail.net> | 2010-06-14 14:07:50 +0000 |
commit | 188019153dcf33ffd9d63ba17ab4a29e95561cce (patch) | |
tree | 647c20b7c73baf4a8f6592d5802fc74ed1c59946 /src/os_unix.c | |
parent | ad3cadd8b2b737c5190b805360f773383843172e (diff) | |
download | sqlite-188019153dcf33ffd9d63ba17ab4a29e95561cce.tar.gz sqlite-188019153dcf33ffd9d63ba17ab4a29e95561cce.zip |
Remove xShmGet/Size/Release from the sqlite3_vfs structure. Change the name of xShmPage to xShmMap. Remove some code that is now unused from os_unix.c and some of the test VFS implementations.
FossilOrigin-Name: fc0cabc15c97dde6a852b4f07df6d30f1d2c04bc
Diffstat (limited to 'src/os_unix.c')
-rw-r--r-- | src/os_unix.c | 261 |
1 files changed, 61 insertions, 200 deletions
diff --git a/src/os_unix.c b/src/os_unix.c index 612d5c436..22c9a9282 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -3128,27 +3128,15 @@ static int unixDeviceCharacteristics(sqlite3_file *NotUsed){ ** Either unixShmNode.mutex must be held or unixShmNode.nRef==0 and ** unixMutexHeld() is true when reading or writing any other field ** in this structure. -** -** To avoid deadlocks, mutex and mutexBuf are always released in the -** reverse order that they are acquired. mutexBuf is always acquired -** first and released last. This invariant is check by asserting -** sqlite3_mutex_notheld() on mutex whenever mutexBuf is acquired or -** released. */ struct unixShmNode { unixInodeInfo *pInode; /* unixInodeInfo that owns this SHM node */ sqlite3_mutex *mutex; /* Mutex to access this object */ - sqlite3_mutex *mutexBuf; /* Mutex to access zBuf[] */ char *zFilename; /* Name of the mmapped file */ int h; /* Open file descriptor */ - - int szMap; /* Size of the mapping into memory */ - char *pMMapBuf; /* Where currently mmapped(). NULL if unmapped */ - - int pgsz; /* Size of shared-memory pages */ - int nPage; /* Size of array apPage */ - char **apPage; /* Array of mapped shared-memory pages */ - + int szRegion; /* Size of shared-memory regions */ + int nRegion; /* Size of array apRegion */ + char **apRegion; /* Array of mapped shared-memory regions */ int nRef; /* Number of unixShm objects pointing to this */ unixShm *pFirst; /* All unixShm objects pointing to this */ #ifdef SQLITE_DEBUG @@ -3175,7 +3163,6 @@ struct unixShm { unixShmNode *pShmNode; /* The underlying unixShmNode object */ unixShm *pNext; /* Next unixShm with the same unixShmNode */ u8 hasMutex; /* True if holding the unixShmNode mutex */ - u8 hasMutexBuf; /* True if holding pFile->mutexBuf */ u16 sharedMask; /* Mask of shared locks held */ u16 exclMask; /* Mask of exclusive locks held */ #ifdef SQLITE_DEBUG @@ -3275,12 +3262,10 @@ static void unixShmPurge(unixFile *pFd){ int i; assert( p->pInode==pFd->pInode ); if( p->mutex ) sqlite3_mutex_free(p->mutex); - if( p->mutexBuf ) sqlite3_mutex_free(p->mutexBuf); - if( p->pMMapBuf ) munmap(p->pMMapBuf, p->szMap); - for(i=0; i<p->nPage; i++){ - munmap(p->apPage[i], p->pgsz); + for(i=0; i<p->nRegion; i++){ + munmap(p->apRegion[i], p->szRegion); } - sqlite3_free(p->apPage); + sqlite3_free(p->apRegion); if( p->h>=0 ) close(p->h); p->pInode->pShmNode = 0; sqlite3_free(p); @@ -3356,11 +3341,6 @@ static int unixShmOpen( rc = SQLITE_NOMEM; goto shm_open_err; } - pShmNode->mutexBuf = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); - if( pShmNode->mutexBuf==0 ){ - rc = SQLITE_NOMEM; - goto shm_open_err; - } pShmNode->h = open(pShmNode->zFilename, O_RDWR|O_CREAT, 0664); if( pShmNode->h<0 ){ @@ -3431,7 +3411,6 @@ static int unixShmClose( *pp = p->pNext; /* Free the connection p */ - assert( p->hasMutexBuf==0 ); sqlite3_free(p); pDbFd->pShm = 0; sqlite3_mutex_leave(pShmNode->mutex); @@ -3451,148 +3430,6 @@ static int unixShmClose( } /* -** Changes the size of the underlying storage for a shared-memory segment. -** -** 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. -*/ -static int unixShmSize( - sqlite3_file *fd, /* The open database file holding SHM */ - int reqSize, /* Requested size. -1 for query only */ - int *pNewSize /* Write new size here */ -){ - unixFile *pDbFd = (unixFile*)fd; - unixShm *p = pDbFd->pShm; - unixShmNode *pShmNode = p->pShmNode; - int rc = SQLITE_OK; - struct stat sStat; - - assert( pShmNode==pDbFd->pInode->pShmNode ); - assert( pShmNode->pInode==pDbFd->pInode ); - - while( 1 ){ - if( fstat(pShmNode->h, &sStat)==0 ){ - *pNewSize = (int)sStat.st_size; - if( reqSize<=(int)sStat.st_size ) break; - }else{ - *pNewSize = 0; - rc = SQLITE_IOERR_SHMSIZE; - break; - } - rc = ftruncate(pShmNode->h, reqSize); - reqSize = -1; - } - return rc; -} - -/* -** Release the lock held on the shared memory segment to that other -** threads are free to resize it if necessary. -** -** If the lock is not currently held, this routine is a harmless no-op. -** -** If the shared-memory object is in lock state RECOVER, then we do not -** really want to release the lock, so in that case too, this routine -** is a no-op. -*/ -static int unixShmRelease(sqlite3_file *fd){ - unixFile *pDbFd = (unixFile*)fd; - unixShm *p = pDbFd->pShm; - - if( p->hasMutexBuf ){ - assert( sqlite3_mutex_notheld(p->pShmNode->mutex) ); - sqlite3_mutex_leave(p->pShmNode->mutexBuf); - p->hasMutexBuf = 0; - } - return SQLITE_OK; -} - -/* -** 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 -** from running while *ppBuf is in use in order to prevent other threads -** remapping *ppBuf out from under this thread. The unixShmRelease() -** call will release the mutex. However, if the lock state is CHECKPOINT, -** the mutex is not acquired because CHECKPOINT will never remap the -** buffer. RECOVER might remap, though, so CHECKPOINT will acquire -** the mutex if and when it promotes to RECOVER. -** -** RECOVER needs to be atomic. The same mutex that prevents *ppBuf from -** being remapped also prevents more than one thread from being in -** RECOVER at a time. But, RECOVER sometimes wants to remap itself. -** 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. 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 might be NULL and zero if no space has -** yet been allocated to the underlying storage. -*/ -static int unixShmGet( - sqlite3_file *fd, /* Database file holding shared memory */ - int reqMapSize, /* Requested size of mapping. -1 means don't care */ - int *pNewMapSize, /* Write new size of mapping here */ - void volatile **ppBuf /* Write mapping buffer origin here */ -){ - unixFile *pDbFd = (unixFile*)fd; - unixShm *p = pDbFd->pShm; - unixShmNode *pShmNode = p->pShmNode; - int rc = SQLITE_OK; - - assert( pShmNode==pDbFd->pInode->pShmNode ); - assert( pShmNode->pInode==pDbFd->pInode ); - - if( p->hasMutexBuf==0 ){ - assert( sqlite3_mutex_notheld(pShmNode->mutex) ); - sqlite3_mutex_enter(pShmNode->mutexBuf); - p->hasMutexBuf = 1; - } - sqlite3_mutex_enter(pShmNode->mutex); - if( pShmNode->szMap==0 || reqMapSize>pShmNode->szMap ){ - int actualSize; - if( unixShmSize(fd, -1, &actualSize)!=SQLITE_OK ){ - actualSize = 0; - } - reqMapSize = actualSize; - if( pShmNode->pMMapBuf || reqMapSize<=0 ){ - munmap(pShmNode->pMMapBuf, pShmNode->szMap); - } - 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; - sqlite3_mutex_leave(pShmNode->mutex); - if( *ppBuf==0 ){ - /* Do not hold the mutex if a NULL pointer is being returned. */ - unixShmRelease(fd); - } - return rc; -} - - -/* ** Change the lock state for a shared-memory segment. ** ** Note that the relationship between SHAREd and EXCLUSIVE locks is a little @@ -3711,16 +3548,35 @@ static int unixShmLock( ** any load or store begun after the barrier. */ static void unixShmBarrier( - sqlite3_file *fd /* Database file holding the shared memory */ + sqlite3_file *fd /* Database file holding the shared memory */ ){ unixEnterMutex(); unixLeaveMutex(); } +/* +** This function is called to obtain a pointer to region iRegion of the +** shared-memory associated with the database file fd. Shared-memory regions +** are numbered starting from zero. Each shared-memory region is szRegion +** bytes in size. +** +** If an error occurs, an error code is returned and *pp is set to NULL. +** +** Otherwise, if the isWrite parameter is 0 and the requested shared-memory +** region has not been allocated (by any client, including one running in a +** separate process), then *pp is set to NULL and SQLITE_OK returned. If +** isWrite is non-zero and the requested shared-memory region has not yet +** been allocated, it is allocated by this function. +** +** If the shared-memory region has already been allocated or is allocated by +** this call as described above, then it is mapped into this processes +** address space (if it is not already), *pp is set to point to the mapped +** memory and SQLITE_OK returned. +*/ static int unixShmPage( sqlite3_file *fd, /* Handle open on database file */ - int iPage, /* Page to retrieve */ - int pgsz, /* Size of pages */ + int iRegion, /* Region to retrieve */ + int szRegion, /* Size of regions */ int isWrite, /* True to extend file if necessary */ void volatile **pp /* OUT: Mapped memory */ ){ @@ -3729,22 +3585,32 @@ static int unixShmPage( unixShmNode *pShmNode = p->pShmNode; int rc = SQLITE_OK; - assert( p->hasMutexBuf==0 ); - sqlite3_mutex_enter(pShmNode->mutexBuf); - assert( pgsz==pShmNode->pgsz || pShmNode->nPage==0 ); + sqlite3_mutex_enter(pShmNode->mutex); + assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 ); - if( pShmNode->nPage<=iPage ){ - char **apNew; /* New apPage[] array */ - int nByte = (iPage+1)*pgsz; /* Minimum required file size */ - struct stat sStat; + if( pShmNode->nRegion<=iRegion ){ + char **apNew; /* New apRegion[] array */ + int nByte = (iRegion+1)*szRegion; /* Minimum required file size */ + struct stat sStat; /* Used by fstat() */ - pShmNode->pgsz = pgsz; + pShmNode->szRegion = szRegion; - /* Make sure the underlying file is large enough (or fail) */ + /* 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( fstat(pShmNode->h, &sStat) ){ rc = SQLITE_IOERR_SHMSIZE; goto shmpage_out; - }else if( sStat.st_size<nByte ){ + } + + if( sStat.st_size<nByte ){ + /* The requested memory region does not exist. If isWrite is set to + ** zero, exit early. *pp will be set to NULL and SQLITE_OK returned. + ** + ** Alternatively, if isWrite is non-zero, use ftruncate() to allocate + ** the requested memory region. + */ if( !isWrite ) goto shmpage_out; if( ftruncate(pShmNode->h, nByte) ){ rc = SQLITE_IOERR_SHMSIZE; @@ -3752,42 +3618,40 @@ static int unixShmPage( } } - apNew = (char**)sqlite3_realloc(pShmNode->apPage, (iPage+1)*sizeof(char *)); + /* Map the requested memory region into this processes address space. */ + apNew = (char **)sqlite3_realloc( + pShmNode->apRegion, (iRegion+1)*sizeof(char *) + ); if( !apNew ){ rc = SQLITE_IOERR_NOMEM; goto shmpage_out; } - pShmNode->apPage = apNew; - - while(pShmNode->nPage<=iPage){ - void *pMem = mmap( - 0, pgsz, PROT_READ|PROT_WRITE, MAP_SHARED, pShmNode->h, iPage*pgsz + pShmNode->apRegion = apNew; + while(pShmNode->nRegion<=iRegion){ + void *pMem = mmap(0, szRegion, PROT_READ|PROT_WRITE, + MAP_SHARED, pShmNode->h, iRegion*szRegion ); if( pMem==MAP_FAILED ){ - assert(0); rc = SQLITE_IOERR; goto shmpage_out; } - pShmNode->apPage[pShmNode->nPage] = pMem; - pShmNode->nPage++; + pShmNode->apRegion[pShmNode->nRegion] = pMem; + pShmNode->nRegion++; } } shmpage_out: - if( pShmNode->nPage>iPage ){ - *pp = pShmNode->apPage[iPage]; + if( pShmNode->nRegion>iRegion ){ + *pp = pShmNode->apRegion[iRegion]; }else{ *pp = 0; } - sqlite3_mutex_leave(pShmNode->mutexBuf); + sqlite3_mutex_leave(pShmNode->mutex); return rc; } #else # define unixShmOpen 0 -# define unixShmSize 0 -# define unixShmGet 0 -# define unixShmRelease 0 # define unixShmLock 0 # define unixShmBarrier 0 # define unixShmClose 0 @@ -3850,9 +3714,6 @@ static const sqlite3_io_methods METHOD = { \ unixSectorSize, /* xSectorSize */ \ unixDeviceCharacteristics, /* xDeviceCapabilities */ \ unixShmOpen, /* xShmOpen */ \ - unixShmSize, /* xShmSize */ \ - unixShmGet, /* xShmGet */ \ - unixShmRelease, /* xShmRelease */ \ unixShmLock, /* xShmLock */ \ unixShmBarrier, /* xShmBarrier */ \ unixShmClose, /* xShmClose */ \ |