aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authordrh <drh@noemail.net>2010-04-26 00:04:55 +0000
committerdrh <drh@noemail.net>2010-04-26 00:04:55 +0000
commitf2424c521bea90fe4c333690a1a7d71554e864fd (patch)
tree50b5b95b83ec401608bee45176534cd26e406905 /src
parent56d95913ebec66dd9d192905f1d08159ae68e32b (diff)
downloadsqlite-f2424c521bea90fe4c333690a1a7d71554e864fd.tar.gz
sqlite-f2424c521bea90fe4c333690a1a7d71554e864fd.zip
Begin moving WAL-specific I/O into the VFS. This checkin contains VFS
infrastructure but it is untested and is not yet hooked up to the WAL. The version number is bumped to 3.7.0 because of the VFS extension. FossilOrigin-Name: f5e615c28c7035a7e6d896790b51cf9bc7371d5f
Diffstat (limited to 'src')
-rw-r--r--src/os_os2.c9
-rw-r--r--src/os_unix.c166
-rw-r--r--src/os_win.c9
-rw-r--r--src/sqlite.h.in39
-rw-r--r--src/test6.c11
-rw-r--r--src/test_demovfs.c11
-rw-r--r--src/test_devsym.c11
-rw-r--r--src/test_journal.c11
-rw-r--r--src/test_onefile.c11
-rw-r--r--src/test_osinst.c11
10 files changed, 278 insertions, 11 deletions
diff --git a/src/os_os2.c b/src/os_os2.c
index 572b6a3c4..04b6dce0e 100644
--- a/src/os_os2.c
+++ b/src/os_os2.c
@@ -1112,6 +1112,15 @@ int sqlite3_os_init(void){
os2Sleep, /* xSleep */
os2CurrentTime, /* xCurrentTime */
os2GetLastError /* xGetLastError */
+ 0, /* xShmOpen */
+ 0, /* xShmSize */
+ 0, /* xShmPush */
+ 0, /* xShmPull */
+ 0, /* xShmLock */
+ 0, /* xShmClose */
+ 0, /* xShmDelete */
+ 0, /* xRename */
+ 0, /* xCurrentTimeInt64 */
};
sqlite3_vfs_register(&os2Vfs, 1);
initUconvObjects();
diff --git a/src/os_unix.c b/src/os_unix.c
index 80ce9e0b0..b2cf9be76 100644
--- a/src/os_unix.c
+++ b/src/os_unix.c
@@ -119,6 +119,7 @@
#include <time.h>
#include <sys/time.h>
#include <errno.h>
+#include <sys/mman.h>
#if SQLITE_ENABLE_LOCKING_STYLE
# include <sys/ioctl.h>
@@ -4562,6 +4563,158 @@ static int unixGetLastError(sqlite3_vfs *NotUsed, int NotUsed2, char *NotUsed3){
}
/*
+** Structure used internally by this VFS to record the state of an
+** open shared memory segment.
+*/
+struct unixShm {
+ sqlite3_vfs *pVfs; /* VFS that opened this shared-memory segment */
+ int size; /* Size of the shared memory area */
+ char *pBuf; /* Pointer to the beginning */
+ unixFile fd; /* The open file descriptor */
+};
+
+/*
+** Close a shared-memory segment
+*/
+static int unixShmClose(sqlite3_shm *pSharedMem){
+ struct unixShm *p = (struct unixShm*)pSharedMem;
+ if( p && p->pVfs ){
+ if( p->pBuf ){
+ munmap(p->pBuf, p->size);
+ }
+ if( p->fd.pMethod ){
+ p->fd.pMethod->xClose((sqlite3_file*)&p->fd);
+ }
+ memset(p, 0, sizeof(*p));
+ sqlite3_free(p);
+ }
+ return SQLITE_OK;
+}
+
+/*
+** Size increment by which shared memory grows
+*/
+#define SQLITE_UNIX_SHM_INCR 4096
+
+/*
+** Open a shared-memory area. This implementation uses mmapped files.
+*/
+static int unixShmOpen(
+ sqlite3_vfs *pVfs, /* The VFS */
+ const char *zName, /* Name of file to mmap */
+ sqlite3_shm **pShm /* Write the unixShm object created here */
+){
+ struct unixShm *p = 0;
+ int rc;
+ int outFlags;
+ struct stat sStat;
+
+ p = sqlite3_malloc( sizeof(*p) );
+ *pShm = (sqlite3_shm*)p;
+ if( p==0 ) return SQLITE_NOMEM;
+ memset(p, 0, sizeof(*p));
+ p->pVfs = pVfs;
+ rc = pVfs->xOpen(pVfs, zName, (sqlite3_file*)&p->fd,
+ SQLITE_OPEN_READWRITE | SQLITE_OPEN_MAIN_JOURNAL,
+ &outFlags);
+ if( rc!=SQLITE_OK ) goto shm_open_err;
+
+ rc = fstat(p->fd.h, &sStat);
+ if( rc!=0 ) goto shm_open_err;
+ if( sStat.st_size<SQLITE_UNIX_SHM_INCR ){
+ rc = ftruncate(p->fd.h, SQLITE_UNIX_SHM_INCR);
+ if( rc!=0 ) goto shm_open_err;
+ p->size = SQLITE_UNIX_SHM_INCR;
+ }else{
+ p->size = sStat.st_size;
+ }
+
+ /* Map the file. */
+ p->pBuf = mmap(0, p->size, PROT_READ|PROT_WRITE, MAP_SHARED, p->fd.h, 0);
+ if( p->pBuf==MAP_FAILED ){
+ rc = SQLITE_IOERR;
+ goto shm_open_err;
+ }
+ return SQLITE_OK;
+
+shm_open_err:
+ unixShmClose((sqlite3_shm*)p);
+ *pShm = 0;
+ return rc;
+}
+
+/*
+** Query and/or changes the size of a shared-memory segment.
+** The reqSize parameter is the new size of the segment, or -1 to
+** do just a query. The size of the segment after resizing is
+** written into pNewSize. The start of the shared memory buffer
+** is stored in **ppBuffer.
+*/
+static int unixShmSize(
+ sqlite3_shm *pSharedMem, /* Pointer returned by unixShmOpen() */
+ int reqSize, /* Requested size. -1 for query only */
+ int *pNewSize, /* Write new size here */
+ char **ppBuf /* Write new buffer origin here */
+){
+ struct unixShm *p = (struct unixShm*)pSharedMem;
+ int rc = SQLITE_OK;
+
+ if( reqSize>=0 ){
+ reqSize = (reqSize + SQLITE_UNIX_SHM_INCR - 1)/SQLITE_UNIX_SHM_INCR;
+ reqSize *= SQLITE_UNIX_SHM_INCR;
+ if( reqSize!=p->size ){
+ munmap(p->pBuf, p->size);
+ rc = ftruncate(p->fd.h, reqSize);
+ if( rc ){
+ p->pBuf = 0;
+ p->size = 0;
+ }else{
+ p->pBuf = mmap(0, reqSize, PROT_READ|PROT_WRITE, MAP_SHARED, p->fd.h,0);
+ p->size = p->pBuf ? reqSize : 0;
+ }
+ }
+ }
+ *pNewSize = p->size;
+ *ppBuf = p->pBuf;
+ return rc;
+}
+
+/*
+** Create or release a lock on shared memory.
+*/
+static int unixShmLock(
+ sqlite3_shm *pSharedMem, /* Pointer from unixShmOpen() */
+ int lockType, /* _RDLK, _WRLK, or _UNLK, possibly ORed _BLOCK */
+ int ofst, /* Start of lock region */
+ int nByte /* Size of lock region in bytes */
+){
+ struct unixShm *p = (struct unixShm*)pSharedMem;
+ struct flock f;
+ int op;
+ int rc;
+
+ f.l_whence = SEEK_SET;
+ f.l_start = ofst;
+ f.l_len = nByte;
+ switch( lockType & 0x07 ){
+ case SQLITE_SHM_RDLK: f.l_type = F_RDLCK; break;
+ case SQLITE_SHM_WRLK: f.l_type = F_WRLCK; break;
+ case SQLITE_SHM_UNLK: f.l_type = F_UNLCK; break;
+ }
+ op = (lockType & 0x08)!=0 ? F_SETLKW : F_SETLK;
+ rc = fcntl(p->fd.h, op, &f);
+ return (rc==0) ? SQLITE_OK : SQLITE_BUSY;
+}
+
+/*
+** Delete a shared-memory segment from the system.
+*/
+static int unixShmDelete(sqlite3_vfs *pVfs, const char *zName){
+ return pVfs->xDelete(pVfs, zName, 0);
+}
+
+
+/*
************************ End of sqlite3_vfs methods ***************************
******************************************************************************/
@@ -5761,7 +5914,7 @@ int sqlite3_os_init(void){
** that filesystem time.
*/
#define UNIXVFS(VFSNAME, FINDER) { \
- 1, /* iVersion */ \
+ 2, /* iVersion */ \
sizeof(unixFile), /* szOsFile */ \
MAX_PATHNAME, /* mxPathname */ \
0, /* pNext */ \
@@ -5778,7 +5931,16 @@ int sqlite3_os_init(void){
unixRandomness, /* xRandomness */ \
unixSleep, /* xSleep */ \
unixCurrentTime, /* xCurrentTime */ \
- unixGetLastError /* xGetLastError */ \
+ unixGetLastError, /* xGetLastError */ \
+ unixShmOpen, /* xShmOpen */ \
+ unixShmSize, /* xShmSize */ \
+ 0, /* xShmPush */ \
+ 0, /* xShmPull */ \
+ unixShmLock, /* xShmLock */ \
+ unixShmClose, /* xShmClose */ \
+ unixShmDelete, /* xShmDelete */ \
+ 0, /* xRename */ \
+ 0, /* xCurrentTimeInt64 */ \
}
/*
diff --git a/src/os_win.c b/src/os_win.c
index 4721eadff..31c3cffce 100644
--- a/src/os_win.c
+++ b/src/os_win.c
@@ -1913,6 +1913,15 @@ int sqlite3_os_init(void){
winSleep, /* xSleep */
winCurrentTime, /* xCurrentTime */
winGetLastError /* xGetLastError */
+ 0, /* xShmOpen */
+ 0, /* xShmSize */
+ 0, /* xShmPush */
+ 0, /* xShmPull */
+ 0, /* xShmLock */
+ 0, /* xShmClose */
+ 0, /* xShmDelete */
+ 0, /* xRename */
+ 0, /* xCurrentTimeInt64 */
};
sqlite3_vfs_register(&winVfs, 1);
diff --git a/src/sqlite.h.in b/src/sqlite.h.in
index 97c97aab0..f673781e0 100644
--- a/src/sqlite.h.in
+++ b/src/sqlite.h.in
@@ -818,8 +818,9 @@ typedef struct sqlite3_mutex sqlite3_mutex;
**
*/
typedef struct sqlite3_vfs sqlite3_vfs;
+typedef struct sqlite3_shm sqlite3_shm;
struct sqlite3_vfs {
- int iVersion; /* Structure version number */
+ int iVersion; /* Structure version number (currently 2) */
int szOsFile; /* Size of subclassed sqlite3_file */
int mxPathname; /* Maximum file pathname length */
sqlite3_vfs *pNext; /* Next registered VFS */
@@ -838,8 +839,24 @@ struct sqlite3_vfs {
int (*xSleep)(sqlite3_vfs*, int microseconds);
int (*xCurrentTime)(sqlite3_vfs*, double*);
int (*xGetLastError)(sqlite3_vfs*, int, char *);
- /* New fields may be appended in figure versions. The iVersion
- ** value will increment whenever this happens. */
+ /*
+ ** The methods above are in version 1 of the sqlite_vfs object
+ ** definition. Those that follow are added in version 2 or later
+ */
+ int (*xShmOpen)(sqlite3_vfs*, const char *zName, sqlite3_shm**);
+ int (*xShmSize)(sqlite3_shm*, int reqSize, int *pNewSize, char **);
+ int (*xShmPush)(sqlite3_shm*);
+ int (*xShmPull)(sqlite3_shm*);
+ int (*xShmLock)(sqlite3_shm*, int lockType, int ofst, int nByte);
+ int (*xShmClose)(sqlite3_shm*);
+ int (*xShmDelete)(sqlite3_vfs*, const char *zName);
+ 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
+ ** value will increment whenever this happens.
+ */
};
/*
@@ -860,6 +877,22 @@ struct sqlite3_vfs {
#define SQLITE_ACCESS_READ 2
/*
+** CAPI3REF: Flags for the xShmLock VFS method
+**
+** These integer constants can be used as the second parameter to
+** the xShmLock method of an [sqlite3_vfs] object. They determine
+** the specific locking action. Exactly one of the first three
+** values must be used ini the lockType parameter. The fourth
+** value (SQLITE_SHM_BLOCK) can optionally be ORed into the lockType
+** parameter to cause the thread to block until the lock becomes
+** available.
+*/
+#define SQLITE_SHM_RDLK 0x01
+#define SQLITE_SHM_WRLK 0x02
+#define SQLITE_SHM_UNLK 0x04
+#define SQLITE_SHM_BLOCK 0x08
+
+/*
** CAPI3REF: Initialize The SQLite Library
**
** ^The sqlite3_initialize() routine initializes the
diff --git a/src/test6.c b/src/test6.c
index b6fa3aadf..a6e995451 100644
--- a/src/test6.c
+++ b/src/test6.c
@@ -781,7 +781,16 @@ static int crashEnableCmd(
cfDlClose, /* xDlClose */
cfRandomness, /* xRandomness */
cfSleep, /* xSleep */
- cfCurrentTime /* xCurrentTime */
+ cfCurrentTime, /* xCurrentTime */
+ 0, /* xShmOpen */
+ 0, /* xShmSize */
+ 0, /* xShmPush */
+ 0, /* xShmPull */
+ 0, /* xShmLock */
+ 0, /* xShmClose */
+ 0, /* xShmDelete */
+ 0, /* xRename */
+ 0 /* xCurrentTimeInt64 */
};
if( objc!=2 ){
diff --git a/src/test_demovfs.c b/src/test_demovfs.c
index 1039d0222..d91a389db 100644
--- a/src/test_demovfs.c
+++ b/src/test_demovfs.c
@@ -623,7 +623,16 @@ sqlite3_vfs *sqlite3_demovfs(void){
demoDlClose, /* xDlClose */
demoRandomness, /* xRandomness */
demoSleep, /* xSleep */
- demoCurrentTime /* xCurrentTime */
+ demoCurrentTime, /* xCurrentTime */
+ 0, /* xShmOpen */
+ 0, /* xShmSize */
+ 0, /* xShmPush */
+ 0, /* xShmPull */
+ 0, /* xShmLock */
+ 0, /* xShmClose */
+ 0, /* xShmDelete */
+ 0, /* xRename */
+ 0 /* xCurrentTimeInt64 */
};
return &demovfs;
}
diff --git a/src/test_devsym.c b/src/test_devsym.c
index 9617e63af..4249573aa 100644
--- a/src/test_devsym.c
+++ b/src/test_devsym.c
@@ -92,7 +92,16 @@ static sqlite3_vfs devsym_vfs = {
#endif /* SQLITE_OMIT_LOAD_EXTENSION */
devsymRandomness, /* xRandomness */
devsymSleep, /* xSleep */
- devsymCurrentTime /* xCurrentTime */
+ devsymCurrentTime, /* xCurrentTime */
+ 0, /* xShmOpen */
+ 0, /* xShmSize */
+ 0, /* xShmPush */
+ 0, /* xShmPull */
+ 0, /* xShmLock */
+ 0, /* xShmClose */
+ 0, /* xShmDelete */
+ 0, /* xRename */
+ 0 /* xCurrentTimeInt64 */
};
static sqlite3_io_methods devsym_io_methods = {
diff --git a/src/test_journal.c b/src/test_journal.c
index f89f3a4c9..fcfe778d1 100644
--- a/src/test_journal.c
+++ b/src/test_journal.c
@@ -179,7 +179,16 @@ static sqlite3_vfs jt_vfs = {
jtDlClose, /* xDlClose */
jtRandomness, /* xRandomness */
jtSleep, /* xSleep */
- jtCurrentTime /* xCurrentTime */
+ jtCurrentTime, /* xCurrentTime */
+ 0, /* xShmOpen */
+ 0, /* xShmSize */
+ 0, /* xShmPush */
+ 0, /* xShmPull */
+ 0, /* xShmLock */
+ 0, /* xShmClose */
+ 0, /* xShmDelete */
+ 0, /* xRename */
+ 0 /* xCurrentTimeInt64 */
};
static sqlite3_io_methods jt_io_methods = {
diff --git a/src/test_onefile.c b/src/test_onefile.c
index 818bd1775..fe02e016e 100644
--- a/src/test_onefile.c
+++ b/src/test_onefile.c
@@ -198,7 +198,16 @@ static fs_vfs_t fs_vfs = {
fsDlClose, /* xDlClose */
fsRandomness, /* xRandomness */
fsSleep, /* xSleep */
- fsCurrentTime /* xCurrentTime */
+ fsCurrentTime, /* xCurrentTime */
+ 0, /* xShmOpen */
+ 0, /* xShmSize */
+ 0, /* xShmPush */
+ 0, /* xShmPull */
+ 0, /* xShmLock */
+ 0, /* xShmClose */
+ 0, /* xShmDelete */
+ 0, /* xRename */
+ 0 /* xCurrentTimeInt64 */
},
0, /* pFileList */
0 /* pParent */
diff --git a/src/test_osinst.c b/src/test_osinst.c
index 283afe60e..c6d16aa67 100644
--- a/src/test_osinst.c
+++ b/src/test_osinst.c
@@ -203,7 +203,16 @@ static sqlite3_vfs inst_vfs = {
instDlClose, /* xDlClose */
instRandomness, /* xRandomness */
instSleep, /* xSleep */
- instCurrentTime /* xCurrentTime */
+ instCurrentTime, /* xCurrentTime */
+ 0, /* xShmOpen */
+ 0, /* xShmSize */
+ 0, /* xShmPush */
+ 0, /* xShmPull */
+ 0, /* xShmLock */
+ 0, /* xShmClose */
+ 0, /* xShmDelete */
+ 0, /* xRename */
+ 0 /* xCurrentTimeInt64 */
};
static sqlite3_io_methods inst_io_methods = {