Index: src/os_unix.c ================================================================== --- src/os_unix.c +++ src/os_unix.c @@ -4921,55 +4921,71 @@ } } } /* -** Open a shared-memory area. This implementation uses mmapped files. +** Open a shared-memory area. This particular implementation uses +** mmapped files. +** +** zName is a filename used to identify the shared-memory area. The +** implementation does not (and perhaps should not) use this name +** directly, but rather use it as a template for finding an appropriate +** name for the shared-memory storage. In this implementation, the +** string "-index" is appended to zName and used as the name of the +** mmapped file. ** ** 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. */ static int unixShmOpen( sqlite3_vfs *pVfs, /* The VFS */ - const char *zName, /* Name of file to mmap */ + const char *zName, /* Base name of file to mmap */ sqlite3_shm **pShm /* Write the unixShm object created here */ ){ struct unixShm *p = 0; /* The connection to be opened */ struct unixShmFile *pFile = 0; /* The underlying mmapped file */ int rc; /* Result code */ struct unixFileId fid; /* Unix file identifier */ + struct unixShmFile *pNew; /* Newly allocated pFile */ struct stat sStat; /* Result from stat() an fstat() */ + int nName; /* Size of zName in bytes */ - /* Allocate space for the new sqlite3_shm object */ + /* Allocate space for the new sqlite3_shm object. Also speculatively + ** allocate space for a new unixShmFile and filename. + */ p = sqlite3_malloc( sizeof(*p) ); if( p==0 ) return SQLITE_NOMEM; memset(p, 0, sizeof(*p)); + nName = strlen(zName); + pNew = sqlite3_malloc( sizeof(*pFile) + nName + 10 ); + if( pNew==0 ){ + rc = SQLITE_NOMEM; + goto shm_open_err; + } + memset(pNew, 0, sizeof(*pNew)); + pNew->zFilename = (char*)&pNew[1]; + sqlite3_snprintf(nName+10, pNew->zFilename, "%s-index", zName); /* Look to see if there is an existing unixShmFile that can be used. ** If no matching unixShmFile currently exists, create a new one. */ unixEnterMutex(); - rc = stat(zName, &sStat); + rc = stat(pNew->zFilename, &sStat); if( rc==0 ){ memset(&fid, 0, sizeof(fid)); fid.dev = sStat.st_dev; fid.ino = sStat.st_ino; for(pFile = unixShmFileList; pFile; pFile=pFile->pNext){ if( memcmp(&pFile->fid, &fid, sizeof(fid))==0 ) break; } } - if( pFile==0 ){ - int nName = strlen(zName); - pFile = sqlite3_malloc( sizeof(*pFile) + nName + 1 ); - if( pFile==0 ){ - rc = SQLITE_NOMEM; - goto shm_open_err; - } - memset(pFile, 0, sizeof(*pFile)); - pFile->zFilename = (char*)&pFile[1]; - memcpy(pFile->zFilename, zName, nName+1); + if( pFile ){ + sqlite3_free(pNew); + }else{ + pFile = pNew; + pNew = 0; pFile->h = -1; pFile->pNext = unixShmFileList; unixShmFileList = pFile; pFile->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); @@ -4981,11 +4997,11 @@ if( pFile->mutexBuf==0 ){ rc = SQLITE_NOMEM; goto shm_open_err; } - pFile->h = open(zName, O_RDWR|O_CREAT, 0664); + pFile->h = open(pFile->zFilename, O_RDWR|O_CREAT, 0664); if( pFile->h<0 ){ rc = SQLITE_CANTOPEN_BKPT; goto shm_open_err; } @@ -5031,19 +5047,21 @@ /* Jump here on any error */ shm_open_err: unixShmPurge(); sqlite3_free(p); sqlite3_free(pFile); + sqlite3_free(pNew); *pShm = 0; unixLeaveMutex(); return rc; } /* -** Close a connectioon to shared-memory. +** Close a connection to shared-memory. Delete the underlying +** storage if deleteFlag is true. */ -static int unixShmClose(sqlite3_shm *pSharedMem){ +static int unixShmClose(sqlite3_shm *pSharedMem, int deleteFlag){ unixShm *p; /* The connection to be closed */ unixShmFile *pFile; /* The underlying shared-memory file */ unixShm **pp; /* For looping over sibling connections */ if( pSharedMem==0 ) return SQLITE_OK; @@ -5067,10 +5085,11 @@ ** shared-memory file, too */ unixEnterMutex(); assert( pFile->nRef>0 ); pFile->nRef--; if( pFile->nRef==0 ){ + if( deleteFlag ) unlink(pFile->zFilename); unixShmPurge(); } unixLeaveMutex(); return SQLITE_OK; @@ -5346,25 +5365,17 @@ p->id, getpid(), azLkName[p->lockState])); if( pGotLock ) *pGotLock = p->lockState; return rc; } -/* -** Delete a shared-memory segment from the system. -*/ -static int unixShmDelete(sqlite3_vfs *pVfs, const char *zName){ - return pVfs->xDelete(pVfs, zName, 0); -} - #else # define unixShmOpen 0 # define unixShmSize 0 # define unixShmGet 0 # define unixShmRelease 0 # define unixShmLock 0 # define unixShmClose 0 -# define unixShmDelete 0 #endif /* #ifndef SQLITE_OMIT_WAL */ /* ************************ End of sqlite3_vfs methods *************************** ******************************************************************************/ @@ -6585,15 +6596,12 @@ unixGetLastError, /* xGetLastError */ \ unixShmOpen, /* xShmOpen */ \ unixShmSize, /* xShmSize */ \ unixShmGet, /* xShmGet */ \ unixShmRelease, /* xShmRelease */ \ - 0, /* xShmPush */ \ - 0, /* xShmPull */ \ unixShmLock, /* xShmLock */ \ unixShmClose, /* xShmClose */ \ - unixShmDelete, /* xShmDelete */ \ 0, /* xRename */ \ 0, /* xCurrentTimeInt64 */ \ } /* Index: src/sqlite.h.in ================================================================== --- src/sqlite.h.in +++ src/sqlite.h.in @@ -845,15 +845,12 @@ */ int (*xShmOpen)(sqlite3_vfs*, const char *zName, sqlite3_shm**); int (*xShmSize)(sqlite3_shm*, int reqSize, int *pNewSize); int (*xShmGet)(sqlite3_shm*, int reqMapSize, int *pMapSize, void**); int (*xShmRelease)(sqlite3_shm*); - int (*xShmPush)(sqlite3_shm*); - int (*xShmPull)(sqlite3_shm*); int (*xShmLock)(sqlite3_shm*, int desiredLock, int *gotLock); - int (*xShmClose)(sqlite3_shm*); - int (*xShmDelete)(sqlite3_vfs*, const char *zName); + int (*xShmClose)(sqlite3_shm*, int deleteFlag); int (*xRename)(sqlite3_vfs*, const char *zOld, const char *zNew, int dirSync); int (*xCurrentTimeInt64)(sqlite3_vfs*, sqlite3_int64*); /* ** The methods above are in versions 1 and 2 of the sqlite_vfs object. ** New fields may be appended in figure versions. The iVersion Index: src/test_devsym.c ================================================================== --- src/test_devsym.c +++ src/test_devsym.c @@ -71,12 +71,11 @@ static int devsymShmOpen(sqlite3_vfs *, const char *, sqlite3_shm **); static int devsymShmSize(sqlite3_shm *, int , int *); static int devsymShmGet(sqlite3_shm *, int , int *, void **); static int devsymShmRelease(sqlite3_shm *); static int devsymShmLock(sqlite3_shm *, int , int *); -static int devsymShmClose(sqlite3_shm *); -static int devsymShmDelete(sqlite3_vfs *, const char *); +static int devsymShmClose(sqlite3_shm *, int); static sqlite3_vfs devsym_vfs = { 2, /* iVersion */ sizeof(devsym_file), /* szOsFile */ DEVSYM_MAX_PATHNAME, /* mxPathname */ @@ -104,15 +103,12 @@ 0, /* xGetLastError */ devsymShmOpen, devsymShmSize, devsymShmGet, devsymShmRelease, - 0, - 0, devsymShmLock, devsymShmClose, - devsymShmDelete, 0, 0, }; static sqlite3_io_methods devsym_io_methods = { @@ -376,15 +372,12 @@ return g.pVfs->xShmRelease(p); } static int devsymShmLock(sqlite3_shm *p, int desiredLock, int *gotLock){ return g.pVfs->xShmLock(p, desiredLock, gotLock); } -static int devsymShmClose(sqlite3_shm *p){ - return g.pVfs->xShmClose(p); -} -static int devsymShmDelete(sqlite3_vfs *pVfs, const char *zName){ - return g.pVfs->xShmDelete(g.pVfs, zName); +static int devsymShmClose(sqlite3_shm *p, int deleteFlag){ + return g.pVfs->xShmClose(p, deleteFlag); } /* ** This procedure registers the devsym vfs with SQLite. If the argument is ** true, the devsym vfs becomes the new default vfs. It is the only publicly @@ -398,11 +391,10 @@ devsym_vfs.xShmSize = (g.pVfs->xShmSize ? devsymShmSize : 0); devsym_vfs.xShmGet = (g.pVfs->xShmGet ? devsymShmGet : 0); devsym_vfs.xShmRelease = (g.pVfs->xShmRelease ? devsymShmRelease : 0); devsym_vfs.xShmLock = (g.pVfs->xShmLock ? devsymShmLock : 0); devsym_vfs.xShmClose = (g.pVfs->xShmClose ? devsymShmClose : 0); - devsym_vfs.xShmDelete = (g.pVfs->xShmDelete ? devsymShmDelete : 0); sqlite3_vfs_register(&devsym_vfs, 0); } if( iDeviceChar>=0 ){ g.iDeviceChar = iDeviceChar; }else{ Index: src/test_onefile.c ================================================================== --- src/test_onefile.c +++ src/test_onefile.c @@ -199,12 +199,10 @@ fsRandomness, /* xRandomness */ fsSleep, /* xSleep */ fsCurrentTime, /* xCurrentTime */ 0, /* xShmOpen */ 0, /* xShmSize */ - 0, /* xShmPush */ - 0, /* xShmPull */ 0, /* xShmLock */ 0, /* xShmClose */ 0, /* xShmDelete */ 0, /* xRename */ 0 /* xCurrentTimeInt64 */ Index: src/wal.c ================================================================== --- src/wal.c +++ src/wal.c @@ -131,10 +131,11 @@ int szWIndex; /* Size of the wal-index that is mapped in mem */ u32 *pWiData; /* Pointer to wal-index content in memory */ u8 lockState; /* SQLITE_SHM_xxxx constant showing lock state */ u8 readerType; /* SQLITE_SHM_READ or SQLITE_SHM_READ_FULL */ WalIndexHdr hdr; /* Wal-index for current snapshot */ + char *zName; /* Name of underlying storage */ }; /* ** This structure is used to implement an iterator that iterates through @@ -588,28 +589,27 @@ if( pVfs->xShmOpen==0 ) return SQLITE_CANTOPEN_BKPT; /* Allocate an instance of struct Wal to return. */ *ppWal = 0; nWal = strlen(zDb); - pRet = (Wal*)sqlite3MallocZero(sizeof(Wal) + pVfs->szOsFile + nWal+11); + pRet = (Wal*)sqlite3MallocZero(sizeof(Wal) + pVfs->szOsFile + nWal+5); if( !pRet ) goto wal_open_out; pRet->pVfs = pVfs; pRet->pFd = (sqlite3_file *)&pRet[1]; - zWal = pVfs->szOsFile + (char*)pRet->pFd; - sqlite3_snprintf(nWal+11, zWal, "%s-wal-index", zDb); + pRet->zName = zWal = pVfs->szOsFile + (char*)pRet->pFd; + sqlite3_snprintf(nWal+5, zWal, "%s-wal", zDb); rc = pVfs->xShmOpen(pVfs, zWal, &pRet->pWIndex); if( rc ) goto wal_open_out; /* Open file handle on the write-ahead log file. */ - zWal[nWal+4] = 0; flags = (SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_MAIN_JOURNAL); rc = sqlite3OsOpen(pVfs, zWal, pRet->pFd, flags, &flags); wal_open_out: if( rc!=SQLITE_OK ){ if( pRet ){ - pVfs->xShmClose(pRet->pWIndex); + pVfs->xShmClose(pRet->pWIndex, 0); sqlite3OsClose(pRet->pFd); sqlite3_free(pRet); } } *ppWal = pRet; @@ -803,19 +803,14 @@ isDelete = 1; } walIndexUnmap(pWal); } - pWal->pVfs->xShmClose(pWal->pWIndex); + pWal->pVfs->xShmClose(pWal->pWIndex, isDelete); sqlite3OsClose(pWal->pFd); if( isDelete ){ - int nWal; - char *zWal = &((char *)pWal->pFd)[pWal->pVfs->szOsFile]; - sqlite3OsDelete(pWal->pVfs, zWal, 0); - nWal = sqlite3Strlen30(zWal); - memcpy(&zWal[nWal], "-index", 7); - pWal->pVfs->xShmDelete(pWal->pVfs, zWal); + sqlite3OsDelete(pWal->pVfs, pWal->zName, 0); } sqlite3_free(pWal); } return rc; }