diff options
author | dan <dan@noemail.net> | 2010-07-13 18:44:03 +0000 |
---|---|---|
committer | dan <dan@noemail.net> | 2010-07-13 18:44:03 +0000 |
commit | da9fe0c327ae952c3e16587e069a878888b3c089 (patch) | |
tree | 51672674ac3f9f56756916f34f48d0bc4663c624 /src/os_unix.c | |
parent | 2103245e75a2b3c9eb76af75700f800d718a66a7 (diff) | |
download | sqlite-da9fe0c327ae952c3e16587e069a878888b3c089.tar.gz sqlite-da9fe0c327ae952c3e16587e069a878888b3c089.zip |
Changes so that the xShmOpen VFS method is no longer required. Its job can be done by the first call to xShmMap. Rename xShmClose to xShmUnmap.
FossilOrigin-Name: f4780bde62c6c19146d2723c101540b8db898d38
Diffstat (limited to 'src/os_unix.c')
-rw-r--r-- | src/os_unix.c | 280 |
1 files changed, 141 insertions, 139 deletions
diff --git a/src/os_unix.c b/src/os_unix.c index 23b558b09..e3fafca08 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -3275,7 +3275,7 @@ static void unixShmPurge(unixFile *pFd){ } /* -** Open a shared-memory area associated with open database file fd. +** Open a shared-memory area associated with open database file pDbFd. ** This particular implementation uses mmapped files. ** ** The file used to implement shared-memory is in the same directory @@ -3294,27 +3294,22 @@ static void unixShmPurge(unixFile *pFd){ ** 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. */ -static int unixShmOpen( - sqlite3_file *fd /* The file descriptor of the associated database */ -){ - struct unixShm *p = 0; /* The connection to be opened */ - struct unixShmNode *pShmNode = 0; /* The underlying mmapped file */ - int rc; /* Result code */ - struct unixFile *pDbFd; /* Underlying database file */ - unixInodeInfo *pInode; /* The inode of fd */ - char *zShmFilename; /* Name of the file used for SHM */ - int nShmFilename; /* Size of the SHM filename in bytes */ - - /* Allocate space for the new sqlite3_shm object. - */ +static int unixOpenSharedMemory(unixFile *pDbFd){ + struct unixShm *p = 0; /* The connection to be opened */ + struct unixShmNode *pShmNode; /* The underlying mmapped file */ + int rc; /* Result code */ + unixInodeInfo *pInode; /* The inode of fd */ + char *zShmFilename; /* Name of the file used for SHM */ + int nShmFilename; /* Size of the SHM filename in bytes */ + + /* Allocate space for the new unixShm object. */ p = sqlite3_malloc( sizeof(*p) ); if( p==0 ) return SQLITE_NOMEM; memset(p, 0, sizeof(*p)); - pDbFd = (struct unixFile*)fd; assert( pDbFd->pShm==0 ); - /* Check to see if a unixShmNode object already exists. Reuse an existing - ** one if present. Create a new one if necessary. + /* Check to see if a unixShmNode object already exists. Reuse an existing + ** one if present. Create a new one if necessary. */ unixEnterMutex(); pInode = pDbFd->pInode; @@ -3380,49 +3375,107 @@ shm_open_err: } /* -** Close a connection to shared-memory. Delete the underlying -** storage if deleteFlag is true. +** 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 bExtend 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 +** bExtend 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 unixShmClose( - sqlite3_file *fd, /* The underlying database file */ - int deleteFlag /* Delete shared-memory if true */ +static int unixShmMap( + sqlite3_file *fd, /* Handle open on database file */ + int iRegion, /* Region to retrieve */ + int szRegion, /* Size of regions */ + int bExtend, /* True to extend file if necessary */ + void volatile **pp /* OUT: Mapped memory */ ){ - unixShm *p; /* The connection to be closed */ - unixShmNode *pShmNode; /* The underlying shared-memory file */ - unixShm **pp; /* For looping over sibling connections */ - unixFile *pDbFd; /* The underlying database file */ + unixFile *pDbFd = (unixFile*)fd; + unixShm *p; + unixShmNode *pShmNode; + int rc = SQLITE_OK; + + /* If the shared-memory file has not yet been opened, open it now. */ + if( pDbFd->pShm==0 ){ + rc = unixOpenSharedMemory(pDbFd); + if( rc!=SQLITE_OK ) return rc; + } - pDbFd = (unixFile*)fd; p = pDbFd->pShm; - if( p==0 ) return SQLITE_OK; pShmNode = p->pShmNode; + sqlite3_mutex_enter(pShmNode->mutex); + assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 ); - assert( pShmNode==pDbFd->pInode->pShmNode ); - assert( pShmNode->pInode==pDbFd->pInode ); + if( pShmNode->nRegion<=iRegion ){ + char **apNew; /* New apRegion[] array */ + int nByte = (iRegion+1)*szRegion; /* Minimum required file size */ + struct stat sStat; /* Used by fstat() */ - /* Remove connection p from the set of connections associated - ** with pShmNode */ - sqlite3_mutex_enter(pShmNode->mutex); - for(pp=&pShmNode->pFirst; (*pp)!=p; pp = &(*pp)->pNext){} - *pp = p->pNext; + pShmNode->szRegion = szRegion; - /* Free the connection p */ - sqlite3_free(p); - pDbFd->pShm = 0; - sqlite3_mutex_leave(pShmNode->mutex); + /* 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; + } - /* If pShmNode->nRef has reached 0, then close the underlying - ** shared-memory file, too */ - unixEnterMutex(); - assert( pShmNode->nRef>0 ); - pShmNode->nRef--; - if( pShmNode->nRef==0 ){ - if( deleteFlag ) unlink(pShmNode->zFilename); - unixShmPurge(pDbFd); + if( sStat.st_size<nByte ){ + /* The requested memory region does not exist. If bExtend is set to + ** false, exit early. *pp will be set to NULL and SQLITE_OK returned. + ** + ** Alternatively, if bExtend is true, use ftruncate() to allocate + ** the requested memory region. + */ + if( !bExtend ) goto shmpage_out; + if( ftruncate(pShmNode->h, nByte) ){ + rc = SQLITE_IOERR_SHMSIZE; + goto shmpage_out; + } + } + + /* 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->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 ){ + rc = SQLITE_IOERR; + goto shmpage_out; + } + pShmNode->apRegion[pShmNode->nRegion] = pMem; + pShmNode->nRegion++; + } } - unixLeaveMutex(); - return SQLITE_OK; +shmpage_out: + if( pShmNode->nRegion>iRegion ){ + *pp = pShmNode->apRegion[iRegion]; + }else{ + *pp = 0; + } + sqlite3_mutex_leave(pShmNode->mutex); + return rc; } /* @@ -3552,107 +3605,57 @@ static void unixShmBarrier( } /* -** 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. +** Close a connection to shared-memory. Delete the underlying +** storage if deleteFlag is true. */ -static int unixShmMap( - sqlite3_file *fd, /* Handle open on database file */ - int iRegion, /* Region to retrieve */ - int szRegion, /* Size of regions */ - int isWrite, /* True to extend file if necessary */ - void volatile **pp /* OUT: Mapped memory */ +static int unixShmUnmap( + sqlite3_file *fd, /* The underlying database file */ + int deleteFlag /* Delete shared-memory if true */ ){ - unixFile *pDbFd = (unixFile*)fd; - unixShm *p = pDbFd->pShm; - unixShmNode *pShmNode = p->pShmNode; - int rc = SQLITE_OK; - - sqlite3_mutex_enter(pShmNode->mutex); - assert( szRegion==pShmNode->szRegion || pShmNode->nRegion==0 ); + unixShm *p; /* The connection to be closed */ + unixShmNode *pShmNode; /* The underlying shared-memory file */ + unixShm **pp; /* For looping over sibling connections */ + unixFile *pDbFd; /* The underlying database file */ - if( pShmNode->nRegion<=iRegion ){ - char **apNew; /* New apRegion[] array */ - int nByte = (iRegion+1)*szRegion; /* Minimum required file size */ - struct stat sStat; /* Used by fstat() */ + pDbFd = (unixFile*)fd; + p = pDbFd->pShm; + if( p==0 ) return SQLITE_OK; + pShmNode = p->pShmNode; - pShmNode->szRegion = szRegion; + assert( pShmNode==pDbFd->pInode->pShmNode ); + assert( pShmNode->pInode==pDbFd->pInode ); - /* 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; - } + /* Remove connection p from the set of connections associated + ** with pShmNode */ + sqlite3_mutex_enter(pShmNode->mutex); + for(pp=&pShmNode->pFirst; (*pp)!=p; pp = &(*pp)->pNext){} + *pp = p->pNext; - 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; - goto shmpage_out; - } - } + /* Free the connection p */ + sqlite3_free(p); + pDbFd->pShm = 0; + sqlite3_mutex_leave(pShmNode->mutex); - /* 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->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 ){ - rc = SQLITE_IOERR; - goto shmpage_out; - } - pShmNode->apRegion[pShmNode->nRegion] = pMem; - pShmNode->nRegion++; - } + /* If pShmNode->nRef has reached 0, then close the underlying + ** shared-memory file, too */ + unixEnterMutex(); + assert( pShmNode->nRef>0 ); + pShmNode->nRef--; + if( pShmNode->nRef==0 ){ + if( deleteFlag ) unlink(pShmNode->zFilename); + unixShmPurge(pDbFd); } + unixLeaveMutex(); -shmpage_out: - if( pShmNode->nRegion>iRegion ){ - *pp = pShmNode->apRegion[iRegion]; - }else{ - *pp = 0; - } - sqlite3_mutex_leave(pShmNode->mutex); - return rc; + return SQLITE_OK; } + #else -# define unixShmOpen 0 -# define unixShmLock 0 # define unixShmMap 0 +# define unixShmLock 0 # define unixShmBarrier 0 -# define unixShmClose 0 +# define unixShmUnmap 0 #endif /* #ifndef SQLITE_OMIT_WAL */ /* @@ -3710,11 +3713,10 @@ static const sqlite3_io_methods METHOD = { \ unixFileControl, /* xFileControl */ \ unixSectorSize, /* xSectorSize */ \ unixDeviceCharacteristics, /* xDeviceCapabilities */ \ - unixShmOpen, /* xShmOpen */ \ - unixShmLock, /* xShmLock */ \ unixShmMap, /* xShmMap */ \ + unixShmLock, /* xShmLock */ \ unixShmBarrier, /* xShmBarrier */ \ - unixShmClose /* xShmClose */ \ + unixShmUnmap /* xShmUnmap */ \ }; \ static const sqlite3_io_methods *FINDER##Impl(const char *z, unixFile *p){ \ UNUSED_PARAMETER(z); UNUSED_PARAMETER(p); \ |