The refactored of VFS SHM primitives are now working so merge the
wal-refactor branch back into the trunk. FossilOrigin-Name: bce21c18380715e894eac9c173c97315e0d69d93
This commit is contained in:
commit
043c20e63e
@ -78,14 +78,24 @@ during testing using an instrumented lock manager.
|
||||
|
||||
(5) No part of the wal-index will be read without holding either some
|
||||
kind of SHM lock or an EXCLUSIVE lock on the original database.
|
||||
The original database is the file named in the 2nd parameter to
|
||||
the xShmOpen method.
|
||||
|
||||
(6) A holder of a READ_FULL will never read any page of the database
|
||||
file that is contained anywhere in the wal-index.
|
||||
|
||||
(7) No part of the wal-index other than the header will be written nor
|
||||
will the size of the wal-index grow without holding a WRITE.
|
||||
will the size of the wal-index grow without holding a WRITE or
|
||||
an EXCLUSIVE on the original database file.
|
||||
|
||||
(8) The wal-index header will not be written without holding one of
|
||||
WRITE, CHECKPOINT, or RECOVER.
|
||||
(9) A CHECKPOINT or RECOVER must be held in order to reset the last valid
|
||||
frame counter in the header of the wal-index back to zero.
|
||||
WRITE, CHECKPOINT, or RECOVER on the wal-index or an EXCLUSIVE on
|
||||
the original database files.
|
||||
|
||||
(9) A CHECKPOINT or RECOVER must be held on the wal-index, or an
|
||||
EXCLUSIVE on the original database file, in order to reset the
|
||||
last valid frame counter in the header of the wal-index back to zero.
|
||||
|
||||
(10) A WRITE can only increase the last valid frame pointer in the header.
|
||||
|
||||
The SQLite core will only ever send requests for UNLOCK, READ, WRITE,
|
||||
|
44
manifest
44
manifest
@ -1,8 +1,8 @@
|
||||
-----BEGIN PGP SIGNED MESSAGE-----
|
||||
Hash: SHA1
|
||||
|
||||
C Remove\sthe\sOP_Variable\soptimization\sof\scheck-in\s[48b77b04935d894]\ssince\sit\ncan\slead\sto\smalfunctions\sas\sdescribed\sin\sticket\s[26ff0c82d1e90].
|
||||
D 2010-05-12T13:50:23
|
||||
C The\srefactored\sof\sVFS\sSHM\sprimitives\sare\snow\sworking\sso\smerge\sthe\s\nwal-refactor\sbranch\sback\sinto\sthe\strunk.
|
||||
D 2010-05-13T08:53:42
|
||||
F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
|
||||
F Makefile.in a5cad1f8f3e021356bfcc6c77dc16f6f1952bbc3
|
||||
F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
|
||||
@ -27,7 +27,7 @@ F configure.ac 14740970ddb674d92a9f5da89083dff1179014ff
|
||||
F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad
|
||||
F doc/lemon.html f0f682f50210928c07e562621c3b7e8ab912a538
|
||||
F doc/pager-invariants.txt 870107036470d7c419e93768676fae2f8749cf9e
|
||||
F doc/vfs-shm.txt 7945d691a41ec90f358f6415095ffe70cfc9fe9e
|
||||
F doc/vfs-shm.txt e101f27ea02a8387ce46a05be2b1a902a021d37a
|
||||
F ext/README.txt 913a7bd3f4837ab14d7e063304181787658b14e1
|
||||
F ext/async/README.txt 0c541f418b14b415212264cbaaf51c924ec62e5b
|
||||
F ext/async/sqlite3async.c 676066c2a111a8b3107aeb59bdbbbf335c348f4a
|
||||
@ -151,14 +151,14 @@ F src/mutex_os2.c 20477db50cf3817c2f1cd3eb61e5c177e50231db
|
||||
F src/mutex_unix.c 04a25238abce7e3d06b358dcf706e26624270809
|
||||
F src/mutex_w32.c 4cc201c1bfd11d1562810554ff5500e735559d7e
|
||||
F src/notify.c cbfa66a836da3a51567209636e6a94059c137930
|
||||
F src/os.c aec6922553585a25d5655666defc125a7e217674
|
||||
F src/os.h b389844e5469a2918e8a45fe6ae52b4c28dfb2b2
|
||||
F src/os.c c0a5dfce2a214dacb679425632d04f8a2021f364
|
||||
F src/os.h 8a7e2456237ecf3a2e55b02f9fe6091f1ad36902
|
||||
F src/os_common.h 0d6ee583b6ee3185eb9d951f890c6dd03021a08d
|
||||
F src/os_os2.c 8ad77a418630d7dee91d1bb04f79c2096301d3a0
|
||||
F src/os_unix.c c306feb1be41283afc47f1da74363d2bde466aae
|
||||
F src/os_unix.c a65eb0c527306fbf8d5818c068cccb4179e2c187
|
||||
F src/os_win.c a8fc01d8483be472e495793c01064fd87e56a5c1
|
||||
F src/pager.c ad9cb3bea70d8b159de1a9b235c94c7abc340956
|
||||
F src/pager.h 934b598583a9d936bb13c37d62a2fe68ac48781c
|
||||
F src/pager.c 1e163a82ae8405433dca559831caa06aafbba3b0
|
||||
F src/pager.h 76466c3a5af56943537f68b1f16567101a0cd1d0
|
||||
F src/parse.y ace5c7a125d9f2a410e431ee3209034105045f7e
|
||||
F src/pcache.c ace8f6a5ecd4711cc66a1b23053be7109bd437cf
|
||||
F src/pcache.h c683390d50f856d4cd8e24342ae62027d1bb6050
|
||||
@ -171,7 +171,7 @@ F src/resolve.c ac5f1a713cd1ae77f08b83cc69581e11bf5ae6f9
|
||||
F src/rowset.c 69afa95a97c524ba6faf3805e717b5b7ae85a697
|
||||
F src/select.c c03d8a0565febcde8c6a12c5d77d065fddae889b
|
||||
F src/shell.c fd4ccdb37c3b68de0623eb938a649e0990710714
|
||||
F src/sqlite.h.in aa54957165356be128b9c8baf3fc66592cb2da7f
|
||||
F src/sqlite.h.in a86bb87f5c9e97ed286a70d515d6c19de031f382
|
||||
F src/sqlite3ext.h 69dfb8116af51b84a029cddb3b35062354270c89
|
||||
F src/sqliteInt.h 9819b45610abeca390176243a9a31758c1f0ac7a
|
||||
F src/sqliteLimit.h 196e2f83c3b444c4548fc1874f52f84fdbda40f3
|
||||
@ -183,7 +183,7 @@ F src/test2.c 31f1b9d076b4774a22d2605d0af1f34e14a9a7bd
|
||||
F src/test3.c 4c21700c73a890a47fc685c1097bfb661346ac94
|
||||
F src/test4.c ad03bb987ddedce928f4258c1e7fa4109a73497d
|
||||
F src/test5.c cc55900118fa4add8ec9cf69fc4225a4662f76b1
|
||||
F src/test6.c 8b9eedc2fee0850636797bcd30a9dd740b449cd7
|
||||
F src/test6.c d00c3930e2d22a9dc84415b1a2ead2ca4ab430ae
|
||||
F src/test7.c 3f2d63e4ccf97f8c2cf1a7fa0a3c8e2e2a354e6e
|
||||
F src/test8.c f959db9a22d882013b64c92753fa793b2ce3bdea
|
||||
F src/test9.c bea1e8cf52aa93695487badedd6e1886c321ea60
|
||||
@ -193,7 +193,7 @@ F src/test_backup.c c129c91127e9b46e335715ae2e75756e25ba27de
|
||||
F src/test_btree.c 47cd771250f09cdc6e12dda5bc71bc0b3abc96e2
|
||||
F src/test_config.c 6210f501d358bde619ae761f06f123529c6ba24f
|
||||
F src/test_demovfs.c da81a5f7785bb352bda7911c332a983ec4f17f27
|
||||
F src/test_devsym.c 257adf02150986902f1f15b478f8a319ecfce7f3
|
||||
F src/test_devsym.c 136869028132c3dc34fe920a9fda716f391227f4
|
||||
F src/test_func.c 13b582345fb1185a93e46c53310fae8547dcce20
|
||||
F src/test_hexio.c 1237f000ec7a491009b1233f5c626ea71bce1ea2
|
||||
F src/test_init.c 5d624ffd0409d424cf9adbfe1f056b200270077c
|
||||
@ -203,14 +203,14 @@ F src/test_journal.c 51da4dd6118ee843349592fde29429fab84a6243
|
||||
F src/test_loadext.c df586c27176e3c2cb2e099c78da67bf14379a56e
|
||||
F src/test_malloc.c 2842c922b8e8d992aba722214952204ca025b411
|
||||
F src/test_mutex.c ce06b59aca168cd8c520b77159a24352a7469bd3
|
||||
F src/test_onefile.c d9585f6e2056868f208b0c21378a05b68c9ceae2
|
||||
F src/test_onefile.c df4d7858b5cd1dffe92d36ec9dbad11f0037ffd1
|
||||
F src/test_osinst.c f5d1a4ee8b80fc58d1430c56146de748584013a9
|
||||
F src/test_pcache.c 7bf828972ac0d2403f5cfa4cd14da41f8ebe73d8
|
||||
F src/test_schema.c 8c06ef9ddb240c7a0fcd31bc221a6a2aade58bf0
|
||||
F src/test_server.c bbba05c144b5fc4b52ff650a4328027b3fa5fcc6
|
||||
F src/test_tclvar.c f4dc67d5f780707210d6bb0eb6016a431c04c7fa
|
||||
F src/test_thread.c aa9919c885a1fe53eafc73492f0898ee6c0a0726
|
||||
F src/test_vfs.c c1e13b5f787042130878996f31827ffb5d4d8efc
|
||||
F src/test_vfs.c 3601f9b6d46cb6daf0697d60c76bf8e18b90b123
|
||||
F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9
|
||||
F src/tokenize.c 25ceb0f0a746ea1d0f9553787f3f0a56853cfaeb
|
||||
F src/trigger.c 8927588cb9e6d47f933b53bfe74200fbb504100d
|
||||
@ -218,7 +218,7 @@ F src/update.c c0dc6b75ad28b76b619042d934f337b02acee208
|
||||
F src/utf.c 1baeeac91707a4df97ccc6141ec0f808278af685
|
||||
F src/util.c 32aebf04c10e51ad3977a928b7416bed671b620b
|
||||
F src/vacuum.c b17355fc10cef0875626932ec2f1fa1deb0daa48
|
||||
F src/vdbe.c f41188f624dccabf9f1fd1cb6af57314857e9dd2
|
||||
F src/vdbe.c 8c6301a7dd844d2d6370ebd46f4e2d0cf449c2de
|
||||
F src/vdbe.h 471f6a3dcec4817ca33596fe7f6654d56c0e75f3
|
||||
F src/vdbeInt.h 19ebc8c2a2e938340051ee65af3f377fb99102d1
|
||||
F src/vdbeapi.c dc3138f10afbc95ed3c21dd25abb154504b1db9d
|
||||
@ -227,8 +227,8 @@ F src/vdbeblob.c 5327132a42a91e8b7acfb60b9d2c3b1c5c863e0e
|
||||
F src/vdbemem.c 2a82f455f6ca6f78b59fb312f96054c04ae0ead1
|
||||
F src/vdbetrace.c 864cef96919323482ebd9986f2132435115e9cc2
|
||||
F src/vtab.c a0f8a40274e4261696ef57aa806de2776ab72cda
|
||||
F src/wal.c 2f747b6a6bfd9b75b837a1e31176235a21342e0f
|
||||
F src/wal.h 32f36b2a827b78373658dac5521291485dfa52b6
|
||||
F src/wal.c 3806c5ed7047debc408665b3576f17bab05b2be6
|
||||
F src/wal.h 434f76f51225bb614e43ccb6bd2341541ba6a06e
|
||||
F src/walker.c 3112bb3afe1d85dc52317cb1d752055e9a781f8f
|
||||
F src/where.c 75fee9e255b62f773fcadd1d1f25b6f63ac7a356
|
||||
F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
|
||||
@ -817,14 +817,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
|
||||
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
|
||||
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
|
||||
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
|
||||
P c501b2ede6aad123bef0aa7ce8b356a134eb6d26
|
||||
R f34b360b99a8eca6d2a66ca5009c7cf8
|
||||
P 7838163d087780a6fb403a17641b96f71baec088 149d2ae4a6fe2f86822f286d2a7092c51bec7ebb
|
||||
R 8a7d44076bf0e05c11800be3998eddd6
|
||||
U drh
|
||||
Z ec71604d99e1c3eded3bf24db26ac01b
|
||||
Z ffd3a6c6136965defa15e38ab4e7a314
|
||||
-----BEGIN PGP SIGNATURE-----
|
||||
Version: GnuPG v1.4.6 (GNU/Linux)
|
||||
|
||||
iD8DBQFL6rIioxKgR168RlERArxoAJ96khmiBmpRdJSt374I6oMPRFYeDgCeJaEi
|
||||
RMst0QQ2MlMNKv1/iZMvQcE=
|
||||
=vEcN
|
||||
iD8DBQFL674ZoxKgR168RlERAsK5AJ4haW8eDmlcRUUp3Yf+C8gRnJAr1gCeNdrT
|
||||
0Fo99N7uchNWHAmE6yfdaFc=
|
||||
=KgrW
|
||||
-----END PGP SIGNATURE-----
|
||||
|
@ -1 +1 @@
|
||||
7838163d087780a6fb403a17641b96f71baec088
|
||||
bce21c18380715e894eac9c173c97315e0d69d93
|
18
src/os.c
18
src/os.c
@ -98,6 +98,24 @@ int sqlite3OsSectorSize(sqlite3_file *id){
|
||||
int sqlite3OsDeviceCharacteristics(sqlite3_file *id){
|
||||
return id->pMethods->xDeviceCharacteristics(id);
|
||||
}
|
||||
int sqlite3OsShmOpen(sqlite3_file *id){
|
||||
return id->pMethods->xShmOpen(id);
|
||||
}
|
||||
int sqlite3OsShmSize(sqlite3_file *id, int reqSize, int *pNewSize){
|
||||
return id->pMethods->xShmSize(id, reqSize, pNewSize);
|
||||
}
|
||||
int sqlite3OsShmGet(sqlite3_file *id, int reqSize, int *pSize, void **pp){
|
||||
return id->pMethods->xShmGet(id, reqSize, pSize, pp);
|
||||
}
|
||||
int sqlite3OsShmRelease(sqlite3_file *id){
|
||||
return id->pMethods->xShmRelease(id);
|
||||
}
|
||||
int sqlite3OsShmLock(sqlite3_file *id, int desiredLock, int *pGotLock){
|
||||
return id->pMethods->xShmLock(id, desiredLock, pGotLock);
|
||||
}
|
||||
int sqlite3OsShmClose(sqlite3_file *id, int deleteFlag){
|
||||
return id->pMethods->xShmClose(id, deleteFlag);
|
||||
}
|
||||
|
||||
/*
|
||||
** The next group of routines are convenience wrappers around the
|
||||
|
6
src/os.h
6
src/os.h
@ -243,6 +243,12 @@ int sqlite3OsFileControl(sqlite3_file*,int,void*);
|
||||
#define SQLITE_FCNTL_DB_UNCHANGED 0xca093fa0
|
||||
int sqlite3OsSectorSize(sqlite3_file *id);
|
||||
int sqlite3OsDeviceCharacteristics(sqlite3_file *id);
|
||||
int sqlite3OsShmOpen(sqlite3_file *id);
|
||||
int sqlite3OsShmSize(sqlite3_file *id, int, int*);
|
||||
int sqlite3OsShmGet(sqlite3_file *id, int, int*, void**);
|
||||
int sqlite3OsShmRelease(sqlite3_file *id);
|
||||
int sqlite3OsShmLock(sqlite3_file *id, int, int*);
|
||||
int sqlite3OsShmClose(sqlite3_file *id, int);
|
||||
|
||||
/*
|
||||
** Functions for accessing sqlite3_vfs methods
|
||||
|
1650
src/os_unix.c
1650
src/os_unix.c
File diff suppressed because it is too large
Load Diff
24
src/pager.c
24
src/pager.c
@ -3077,7 +3077,7 @@ int sqlite3PagerClose(Pager *pPager){
|
||||
pPager->errCode = 0;
|
||||
pPager->exclusiveMode = 0;
|
||||
#ifndef SQLITE_OMIT_WAL
|
||||
sqlite3WalClose(pPager->pWal, pPager->fd,
|
||||
sqlite3WalClose(pPager->pWal,
|
||||
(pPager->noSync ? 0 : pPager->sync_flags),
|
||||
pPager->pageSize, pTmp
|
||||
);
|
||||
@ -5878,7 +5878,7 @@ int sqlite3PagerCheckpoint(Pager *pPager){
|
||||
int rc = SQLITE_OK;
|
||||
if( pPager->pWal ){
|
||||
u8 *zBuf = (u8 *)pPager->pTmpSpace;
|
||||
rc = sqlite3WalCheckpoint(pPager->pWal, pPager->fd,
|
||||
rc = sqlite3WalCheckpoint(pPager->pWal,
|
||||
(pPager->noSync ? 0 : pPager->sync_flags),
|
||||
pPager->pageSize, zBuf,
|
||||
pPager->xBusyHandler, pPager->pBusyHandlerArg
|
||||
@ -5891,6 +5891,15 @@ int sqlite3PagerWalCallback(Pager *pPager){
|
||||
return sqlite3WalCallback(pPager->pWal);
|
||||
}
|
||||
|
||||
/*
|
||||
** Return true if the underlying VFS for the given pager supports the
|
||||
** primitives necessary for write-ahead logging.
|
||||
*/
|
||||
int sqlite3PagerWalSupported(Pager *pPager){
|
||||
const sqlite3_io_methods *pMethods = pPager->fd->pMethods;
|
||||
return pMethods->iVersion>=2 && pMethods->xShmOpen!=0;
|
||||
}
|
||||
|
||||
/*
|
||||
** Open a connection to the write-ahead log file for pager pPager. If
|
||||
** the log connection is already open, this function is a no-op.
|
||||
@ -5903,12 +5912,14 @@ int sqlite3PagerOpenWal(Pager *pPager, int *pisOpen){
|
||||
|
||||
assert( pPager->state>=PAGER_SHARED );
|
||||
if( !pPager->pWal ){
|
||||
if( !sqlite3PagerWalSupported(pPager) ) return SQLITE_CANTOPEN;
|
||||
|
||||
/* Open the connection to the log file. If this operation fails,
|
||||
** (e.g. due to malloc() failure), unlock the database file and
|
||||
** return an error code.
|
||||
*/
|
||||
rc = sqlite3WalOpen(pPager->pVfs, pPager->zFilename, &pPager->pWal);
|
||||
rc = sqlite3WalOpen(pPager->pVfs, pPager->fd,
|
||||
pPager->zFilename, &pPager->pWal);
|
||||
if( rc==SQLITE_OK ){
|
||||
pPager->journalMode = PAGER_JOURNALMODE_WAL;
|
||||
}
|
||||
@ -5944,7 +5955,8 @@ int sqlite3PagerCloseWal(Pager *pPager){
|
||||
rc = pagerHasWAL(pPager, &logexists);
|
||||
}
|
||||
if( rc==SQLITE_OK && logexists ){
|
||||
rc = sqlite3WalOpen(pPager->pVfs, pPager->zFilename, &pPager->pWal);
|
||||
rc = sqlite3WalOpen(pPager->pVfs, pPager->fd,
|
||||
pPager->zFilename, &pPager->pWal);
|
||||
}
|
||||
}
|
||||
|
||||
@ -5954,8 +5966,8 @@ int sqlite3PagerCloseWal(Pager *pPager){
|
||||
if( rc==SQLITE_OK && pPager->pWal ){
|
||||
rc = sqlite3OsLock(pPager->fd, SQLITE_LOCK_EXCLUSIVE);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3WalClose(pPager->pWal, pPager->fd,
|
||||
(pPager->noSync ? 0 : pPager->sync_flags),
|
||||
rc = sqlite3WalClose(pPager->pWal,
|
||||
(pPager->noSync ? 0 : pPager->sync_flags),
|
||||
pPager->pageSize, (u8*)pPager->pTmpSpace
|
||||
);
|
||||
pPager->pWal = 0;
|
||||
|
@ -135,6 +135,7 @@ int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint);
|
||||
int sqlite3PagerSharedLock(Pager *pPager);
|
||||
|
||||
int sqlite3PagerCheckpoint(Pager *pPager);
|
||||
int sqlite3PagerWalSupported(Pager *pPager);
|
||||
int sqlite3PagerWalCallback(Pager *pPager);
|
||||
int sqlite3PagerOpenWal(Pager *pPager, int *pisOpen);
|
||||
int sqlite3PagerCloseWal(Pager *pPager);
|
||||
|
@ -653,6 +653,14 @@ struct sqlite3_io_methods {
|
||||
int (*xFileControl)(sqlite3_file*, int op, void *pArg);
|
||||
int (*xSectorSize)(sqlite3_file*);
|
||||
int (*xDeviceCharacteristics)(sqlite3_file*);
|
||||
/* Methods above are valid for version 1 */
|
||||
int (*xShmOpen)(sqlite3_file*);
|
||||
int (*xShmSize)(sqlite3_file*, int reqSize, int *pNewSize);
|
||||
int (*xShmGet)(sqlite3_file*, int reqSize, int *pSize, void**);
|
||||
int (*xShmRelease)(sqlite3_file*);
|
||||
int (*xShmLock)(sqlite3_file*, int desiredLock, int *gotLock);
|
||||
int (*xShmClose)(sqlite3_file*, int deleteFlag);
|
||||
/* Methods above are valid for version 2 */
|
||||
/* Additional methods may be added in future releases */
|
||||
};
|
||||
|
||||
@ -818,7 +826,6 @@ 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 (currently 2) */
|
||||
int szOsFile; /* Size of subclassed sqlite3_file */
|
||||
@ -843,12 +850,6 @@ struct sqlite3_vfs {
|
||||
** 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_vfs*, sqlite3_shm*, int reqSize, int *pNewSize);
|
||||
int (*xShmGet)(sqlite3_vfs*, sqlite3_shm*, int reqSize, int *pSize, void**);
|
||||
int (*xShmRelease)(sqlite3_vfs*, sqlite3_shm*);
|
||||
int (*xShmLock)(sqlite3_vfs*, sqlite3_shm*, int desiredLock, int *gotLock);
|
||||
int (*xShmClose)(sqlite3_vfs*, sqlite3_shm*, int deleteFlag);
|
||||
int (*xRename)(sqlite3_vfs*, const char *zOld, const char *zNew, int dirSync);
|
||||
int (*xCurrentTimeInt64)(sqlite3_vfs*, sqlite3_int64*);
|
||||
/*
|
||||
|
71
src/test6.c
71
src/test6.c
@ -520,8 +520,31 @@ static int cfDeviceCharacteristics(sqlite3_file *pFile){
|
||||
return g.iDeviceCharacteristics;
|
||||
}
|
||||
|
||||
/*
|
||||
** Pass-throughs for WAL support.
|
||||
*/
|
||||
static int cfShmOpen(sqlite3_file *pFile){
|
||||
return sqlite3OsShmOpen(((CrashFile*)pFile)->pRealFile);
|
||||
}
|
||||
static int cfShmSize(sqlite3_file *pFile, int reqSize, int *pNew){
|
||||
return sqlite3OsShmSize(((CrashFile*)pFile)->pRealFile, reqSize, pNew);
|
||||
}
|
||||
static int cfShmGet(sqlite3_file *pFile, int reqSize, int *pSize, void **pp){
|
||||
return sqlite3OsShmGet(((CrashFile*)pFile)->pRealFile, reqSize, pSize, pp);
|
||||
}
|
||||
static int cfShmRelease(sqlite3_file *pFile){
|
||||
return sqlite3OsShmRelease(((CrashFile*)pFile)->pRealFile);
|
||||
}
|
||||
static int cfShmLock(sqlite3_file *pFile, int desired, int *pGot){
|
||||
return sqlite3OsShmLock(((CrashFile*)pFile)->pRealFile, desired, pGot);
|
||||
}
|
||||
static int cfShmClose(sqlite3_file *pFile, int delFlag){
|
||||
return sqlite3OsShmClose(((CrashFile*)pFile)->pRealFile, delFlag);
|
||||
}
|
||||
|
||||
|
||||
static const sqlite3_io_methods CrashFileVtab = {
|
||||
1, /* iVersion */
|
||||
2, /* iVersion */
|
||||
cfClose, /* xClose */
|
||||
cfRead, /* xRead */
|
||||
cfWrite, /* xWrite */
|
||||
@ -533,7 +556,13 @@ static const sqlite3_io_methods CrashFileVtab = {
|
||||
cfCheckReservedLock, /* xCheckReservedLock */
|
||||
cfFileControl, /* xFileControl */
|
||||
cfSectorSize, /* xSectorSize */
|
||||
cfDeviceCharacteristics /* xDeviceCharacteristics */
|
||||
cfDeviceCharacteristics, /* xDeviceCharacteristics */
|
||||
cfShmOpen, /* xShmOpen */
|
||||
cfShmSize, /* xShmSize */
|
||||
cfShmGet, /* xShmGet */
|
||||
cfShmRelease, /* xShmRelease */
|
||||
cfShmLock, /* xShmLock */
|
||||
cfShmClose /* xShmClose */
|
||||
};
|
||||
|
||||
/*
|
||||
@ -657,33 +686,6 @@ static int cfCurrentTime(sqlite3_vfs *pCfVfs, double *pTimeOut){
|
||||
sqlite3_vfs *pVfs = (sqlite3_vfs *)pCfVfs->pAppData;
|
||||
return pVfs->xCurrentTime(pVfs, pTimeOut);
|
||||
}
|
||||
static int cfShmOpen(sqlite3_vfs *pCfVfs, const char *zName, sqlite3_shm **pp){
|
||||
sqlite3_vfs *pVfs = (sqlite3_vfs *)pCfVfs->pAppData;
|
||||
return pVfs->xShmOpen(pVfs, zName, pp);
|
||||
}
|
||||
static int cfShmSize(sqlite3_vfs *pCfVfs, sqlite3_shm *p,
|
||||
int reqSize, int *pNew){
|
||||
sqlite3_vfs *pVfs = (sqlite3_vfs *)pCfVfs->pAppData;
|
||||
return pVfs->xShmSize(pVfs, p, reqSize, pNew);
|
||||
}
|
||||
static int cfShmGet(sqlite3_vfs *pCfVfs, sqlite3_shm *p,
|
||||
int reqSize, int *pSize, void **pp){
|
||||
sqlite3_vfs *pVfs = (sqlite3_vfs *)pCfVfs->pAppData;
|
||||
return pVfs->xShmGet(pVfs, p, reqSize, pSize, pp);
|
||||
}
|
||||
static int cfShmRelease(sqlite3_vfs *pCfVfs, sqlite3_shm *p){
|
||||
sqlite3_vfs *pVfs = (sqlite3_vfs *)pCfVfs->pAppData;
|
||||
return pVfs->xShmRelease(pVfs, p);
|
||||
}
|
||||
static int cfShmLock(sqlite3_vfs *pCfVfs, sqlite3_shm *p,
|
||||
int desiredLock, int *gotLock){
|
||||
sqlite3_vfs *pVfs = (sqlite3_vfs *)pCfVfs->pAppData;
|
||||
return pVfs->xShmLock(pVfs, p, desiredLock, gotLock);
|
||||
}
|
||||
static int cfShmClose(sqlite3_vfs *pCfVfs, sqlite3_shm *p, int delFlag){
|
||||
sqlite3_vfs *pVfs = (sqlite3_vfs *)pCfVfs->pAppData;
|
||||
return pVfs->xShmClose(pVfs, p, delFlag);
|
||||
}
|
||||
|
||||
static int processDevSymArgs(
|
||||
Tcl_Interp *interp,
|
||||
@ -810,12 +812,6 @@ static int crashEnableCmd(
|
||||
cfSleep, /* xSleep */
|
||||
cfCurrentTime, /* xCurrentTime */
|
||||
0, /* xGetlastError */
|
||||
cfShmOpen, /* xShmOpen */
|
||||
cfShmSize, /* xShmSize */
|
||||
cfShmGet, /* xShmGet */
|
||||
cfShmRelease, /* xShmRelease */
|
||||
cfShmLock, /* xShmLock */
|
||||
cfShmClose, /* xShmClose */
|
||||
0, /* xRename */
|
||||
0, /* xCurrentTimeInt64 */
|
||||
};
|
||||
@ -838,11 +834,6 @@ static int crashEnableCmd(
|
||||
crashVfs.mxPathname = pOriginalVfs->mxPathname;
|
||||
crashVfs.pAppData = (void *)pOriginalVfs;
|
||||
crashVfs.szOsFile = sizeof(CrashFile) + pOriginalVfs->szOsFile;
|
||||
if( pOriginalVfs->iVersion<2 || pOriginalVfs->xShmOpen==0 ){
|
||||
crashVfs.xShmOpen = 0;
|
||||
}else{
|
||||
crashVfs.xShmOpen = cfShmOpen;
|
||||
}
|
||||
sqlite3_vfs_register(&crashVfs, 0);
|
||||
}else{
|
||||
crashVfs.pAppData = 0;
|
||||
|
@ -50,6 +50,12 @@ static int devsymCheckReservedLock(sqlite3_file*, int *);
|
||||
static int devsymFileControl(sqlite3_file*, int op, void *pArg);
|
||||
static int devsymSectorSize(sqlite3_file*);
|
||||
static int devsymDeviceCharacteristics(sqlite3_file*);
|
||||
static int devsymShmOpen(sqlite3_file*);
|
||||
static int devsymShmSize(sqlite3_file*,int,int*);
|
||||
static int devsymShmGet(sqlite3_file*,int,int*,void**);
|
||||
static int devsymShmRelease(sqlite3_file*);
|
||||
static int devsymShmLock(sqlite3_file*,int,int*);
|
||||
static int devsymShmClose(sqlite3_file*,int);
|
||||
|
||||
/*
|
||||
** Method declarations for devsym_vfs.
|
||||
@ -68,13 +74,6 @@ static int devsymRandomness(sqlite3_vfs*, int nByte, char *zOut);
|
||||
static int devsymSleep(sqlite3_vfs*, int microseconds);
|
||||
static int devsymCurrentTime(sqlite3_vfs*, double*);
|
||||
|
||||
static int devsymShmOpen(sqlite3_vfs *, const char *, sqlite3_shm **);
|
||||
static int devsymShmSize(sqlite3_vfs*, sqlite3_shm *, int , int *);
|
||||
static int devsymShmGet(sqlite3_vfs*, sqlite3_shm *, int , int *, void **);
|
||||
static int devsymShmRelease(sqlite3_vfs*, sqlite3_shm *);
|
||||
static int devsymShmLock(sqlite3_vfs*, sqlite3_shm *, int , int *);
|
||||
static int devsymShmClose(sqlite3_vfs*, sqlite3_shm *, int);
|
||||
|
||||
static sqlite3_vfs devsym_vfs = {
|
||||
2, /* iVersion */
|
||||
sizeof(devsym_file), /* szOsFile */
|
||||
@ -101,18 +100,12 @@ static sqlite3_vfs devsym_vfs = {
|
||||
devsymSleep, /* xSleep */
|
||||
devsymCurrentTime, /* xCurrentTime */
|
||||
0, /* xGetLastError */
|
||||
devsymShmOpen,
|
||||
devsymShmSize,
|
||||
devsymShmGet,
|
||||
devsymShmRelease,
|
||||
devsymShmLock,
|
||||
devsymShmClose,
|
||||
0,
|
||||
0,
|
||||
0, /* xRename */
|
||||
0 /* xCurrentTimeInt64 */
|
||||
};
|
||||
|
||||
static sqlite3_io_methods devsym_io_methods = {
|
||||
1, /* iVersion */
|
||||
2, /* iVersion */
|
||||
devsymClose, /* xClose */
|
||||
devsymRead, /* xRead */
|
||||
devsymWrite, /* xWrite */
|
||||
@ -124,7 +117,13 @@ static sqlite3_io_methods devsym_io_methods = {
|
||||
devsymCheckReservedLock, /* xCheckReservedLock */
|
||||
devsymFileControl, /* xFileControl */
|
||||
devsymSectorSize, /* xSectorSize */
|
||||
devsymDeviceCharacteristics /* xDeviceCharacteristics */
|
||||
devsymDeviceCharacteristics, /* xDeviceCharacteristics */
|
||||
devsymShmOpen, /* xShmOpen */
|
||||
devsymShmSize, /* xShmSize */
|
||||
devsymShmGet, /* xShmGet */
|
||||
devsymShmRelease, /* xShmRelease */
|
||||
devsymShmLock, /* xShmLock */
|
||||
devsymShmClose /* xShmClose */
|
||||
};
|
||||
|
||||
struct DevsymGlobal {
|
||||
@ -238,6 +237,36 @@ static int devsymDeviceCharacteristics(sqlite3_file *pFile){
|
||||
return g.iDeviceChar;
|
||||
}
|
||||
|
||||
/*
|
||||
** Shared-memory methods are all pass-thrus.
|
||||
*/
|
||||
static int devsymShmOpen(sqlite3_file *pFile){
|
||||
devsym_file *p = (devsym_file *)pFile;
|
||||
return sqlite3OsShmOpen(p->pReal);
|
||||
}
|
||||
static int devsymShmSize(sqlite3_file *pFile, int reqSize, int *pSize){
|
||||
devsym_file *p = (devsym_file *)pFile;
|
||||
return sqlite3OsShmSize(p->pReal, reqSize, pSize);
|
||||
}
|
||||
static int devsymShmGet(sqlite3_file *pFile, int reqSz, int *pSize, void **pp){
|
||||
devsym_file *p = (devsym_file *)pFile;
|
||||
return sqlite3OsShmGet(p->pReal, reqSz, pSize, pp);
|
||||
}
|
||||
static int devsymShmRelease(sqlite3_file *pFile){
|
||||
devsym_file *p = (devsym_file *)pFile;
|
||||
return sqlite3OsShmRelease(p->pReal);
|
||||
}
|
||||
static int devsymShmLock(sqlite3_file *pFile, int desired, int *pGot){
|
||||
devsym_file *p = (devsym_file *)pFile;
|
||||
return sqlite3OsShmLock(p->pReal, desired, pGot);
|
||||
}
|
||||
static int devsymShmClose(sqlite3_file *pFile, int delFlag){
|
||||
devsym_file *p = (devsym_file *)pFile;
|
||||
return sqlite3OsShmClose(p->pReal, delFlag);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
** Open an devsym file handle.
|
||||
*/
|
||||
@ -350,45 +379,6 @@ static int devsymCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){
|
||||
}
|
||||
|
||||
|
||||
static int devsymShmOpen(
|
||||
sqlite3_vfs *pVfs,
|
||||
const char *zName,
|
||||
sqlite3_shm **pp
|
||||
){
|
||||
return g.pVfs->xShmOpen(g.pVfs, zName, pp);
|
||||
}
|
||||
static int devsymShmSize(
|
||||
sqlite3_vfs *pVfs,
|
||||
sqlite3_shm *p,
|
||||
int reqSize,
|
||||
int *pNewSize
|
||||
){
|
||||
return g.pVfs->xShmSize(g.pVfs, p, reqSize, pNewSize);
|
||||
}
|
||||
static int devsymShmGet(
|
||||
sqlite3_vfs *pVfs,
|
||||
sqlite3_shm *p,
|
||||
int reqMapSize,
|
||||
int *pMapSize,
|
||||
void **pp
|
||||
){
|
||||
return g.pVfs->xShmGet(g.pVfs, p, reqMapSize, pMapSize, pp);
|
||||
}
|
||||
static int devsymShmRelease(sqlite3_vfs *pVfs, sqlite3_shm *p){
|
||||
return g.pVfs->xShmRelease(g.pVfs, p);
|
||||
}
|
||||
static int devsymShmLock(
|
||||
sqlite3_vfs *pVfs,
|
||||
sqlite3_shm *p,
|
||||
int desiredLock,
|
||||
int *gotLock
|
||||
){
|
||||
return g.pVfs->xShmLock(g.pVfs, p, desiredLock, gotLock);
|
||||
}
|
||||
static int devsymShmClose(sqlite3_vfs *pVfs, sqlite3_shm *p, int deleteFlag){
|
||||
return g.pVfs->xShmClose(g.pVfs, 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,12 +388,6 @@ void devsym_register(int iDeviceChar, int iSectorSize){
|
||||
if( g.pVfs==0 ){
|
||||
g.pVfs = sqlite3_vfs_find(0);
|
||||
devsym_vfs.szOsFile += g.pVfs->szOsFile;
|
||||
devsym_vfs.xShmOpen = (g.pVfs->xShmOpen ? devsymShmOpen : 0);
|
||||
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);
|
||||
sqlite3_vfs_register(&devsym_vfs, 0);
|
||||
}
|
||||
if( iDeviceChar>=0 ){
|
||||
|
@ -199,11 +199,6 @@ static fs_vfs_t fs_vfs = {
|
||||
fsRandomness, /* xRandomness */
|
||||
fsSleep, /* xSleep */
|
||||
fsCurrentTime, /* xCurrentTime */
|
||||
0, /* xShmOpen */
|
||||
0, /* xShmSize */
|
||||
0, /* xShmLock */
|
||||
0, /* xShmClose */
|
||||
0, /* xShmDelete */
|
||||
0, /* xRename */
|
||||
0 /* xCurrentTimeInt64 */
|
||||
},
|
||||
@ -224,7 +219,12 @@ static sqlite3_io_methods fs_io_methods = {
|
||||
fsCheckReservedLock, /* xCheckReservedLock */
|
||||
fsFileControl, /* xFileControl */
|
||||
fsSectorSize, /* xSectorSize */
|
||||
fsDeviceCharacteristics /* xDeviceCharacteristics */
|
||||
fsDeviceCharacteristics, /* xDeviceCharacteristics */
|
||||
0, /* xShmOpen */
|
||||
0, /* xShmSize */
|
||||
0, /* xShmLock */
|
||||
0, /* xShmClose */
|
||||
0, /* xShmDelete */
|
||||
};
|
||||
|
||||
|
||||
@ -241,7 +241,12 @@ static sqlite3_io_methods tmp_io_methods = {
|
||||
tmpCheckReservedLock, /* xCheckReservedLock */
|
||||
tmpFileControl, /* xFileControl */
|
||||
tmpSectorSize, /* xSectorSize */
|
||||
tmpDeviceCharacteristics /* xDeviceCharacteristics */
|
||||
tmpDeviceCharacteristics, /* xDeviceCharacteristics */
|
||||
0, /* xShmOpen */
|
||||
0, /* xShmSize */
|
||||
0, /* xShmLock */
|
||||
0, /* xShmClose */
|
||||
0, /* xShmDelete */
|
||||
};
|
||||
|
||||
/* Useful macros used in several places */
|
||||
|
213
src/test_vfs.c
213
src/test_vfs.c
@ -16,15 +16,23 @@
|
||||
#include "sqlite3.h"
|
||||
#include "sqliteInt.h"
|
||||
|
||||
typedef struct tvfs_file tvfs_file;
|
||||
struct tvfs_file {
|
||||
sqlite3_file base;
|
||||
sqlite3_file *pReal;
|
||||
};
|
||||
|
||||
typedef struct Testvfs Testvfs;
|
||||
typedef struct TestvfsShm TestvfsShm;
|
||||
typedef struct TestvfsBuffer TestvfsBuffer;
|
||||
typedef struct TestvfsFile TestvfsFile;
|
||||
|
||||
/*
|
||||
** An open file handle.
|
||||
*/
|
||||
struct TestvfsFile {
|
||||
sqlite3_file base; /* Base class. Must be first */
|
||||
sqlite3_vfs *pVfs; /* The VFS */
|
||||
const char *zFilename; /* Filename as passed to xOpen() */
|
||||
sqlite3_file *pReal; /* The real, underlying file descriptor */
|
||||
Tcl_Obj *pShmId; /* Shared memory id for Tcl callbacks */
|
||||
TestvfsBuffer *pShm; /* Shared memory buffer */
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
** An instance of this structure is allocated for each VFS created. The
|
||||
@ -39,6 +47,7 @@ struct Testvfs {
|
||||
int nScript; /* Number of elements in array apScript */
|
||||
Tcl_Obj **apScript; /* Script to execute */
|
||||
TestvfsBuffer *pBuffer; /* List of shared buffers */
|
||||
int isNoshm;
|
||||
};
|
||||
|
||||
/*
|
||||
@ -52,20 +61,12 @@ struct TestvfsBuffer {
|
||||
TestvfsBuffer *pNext; /* Next in linked list of all buffers */
|
||||
};
|
||||
|
||||
/*
|
||||
** A shared-memory handle returned by tvfsShmOpen().
|
||||
*/
|
||||
struct TestvfsShm {
|
||||
Tcl_Obj *id; /* Name of this handle */
|
||||
TestvfsBuffer *pBuffer; /* Underlying buffer */
|
||||
};
|
||||
|
||||
|
||||
#define PARENTVFS(x) (((Testvfs *)((x)->pAppData))->pParent)
|
||||
|
||||
|
||||
/*
|
||||
** Method declarations for tvfs_file.
|
||||
** Method declarations for TestvfsFile.
|
||||
*/
|
||||
static int tvfsClose(sqlite3_file*);
|
||||
static int tvfsRead(sqlite3_file*, void*, int iAmt, sqlite3_int64 iOfst);
|
||||
@ -97,15 +98,15 @@ static int tvfsRandomness(sqlite3_vfs*, int nByte, char *zOut);
|
||||
static int tvfsSleep(sqlite3_vfs*, int microseconds);
|
||||
static int tvfsCurrentTime(sqlite3_vfs*, double*);
|
||||
|
||||
static int tvfsShmOpen(sqlite3_vfs *, const char *, sqlite3_shm **);
|
||||
static int tvfsShmSize(sqlite3_vfs*, sqlite3_shm *, int , int *);
|
||||
static int tvfsShmGet(sqlite3_vfs*, sqlite3_shm *, int , int *, void **);
|
||||
static int tvfsShmRelease(sqlite3_vfs*, sqlite3_shm *);
|
||||
static int tvfsShmLock(sqlite3_vfs*, sqlite3_shm *, int , int *);
|
||||
static int tvfsShmClose(sqlite3_vfs*, sqlite3_shm *, int);
|
||||
static int tvfsShmOpen(sqlite3_file*);
|
||||
static int tvfsShmSize(sqlite3_file*, int , int *);
|
||||
static int tvfsShmGet(sqlite3_file*, int , int *, void **);
|
||||
static int tvfsShmRelease(sqlite3_file*);
|
||||
static int tvfsShmLock(sqlite3_file*, int , int *);
|
||||
static int tvfsShmClose(sqlite3_file*, int);
|
||||
|
||||
static sqlite3_io_methods tvfs_io_methods = {
|
||||
1, /* iVersion */
|
||||
2, /* iVersion */
|
||||
tvfsClose, /* xClose */
|
||||
tvfsRead, /* xRead */
|
||||
tvfsWrite, /* xWrite */
|
||||
@ -117,14 +118,27 @@ static sqlite3_io_methods tvfs_io_methods = {
|
||||
tvfsCheckReservedLock, /* xCheckReservedLock */
|
||||
tvfsFileControl, /* xFileControl */
|
||||
tvfsSectorSize, /* xSectorSize */
|
||||
tvfsDeviceCharacteristics /* xDeviceCharacteristics */
|
||||
tvfsDeviceCharacteristics, /* xDeviceCharacteristics */
|
||||
tvfsShmOpen, /* xShmOpen */
|
||||
tvfsShmSize, /* xShmSize */
|
||||
tvfsShmGet, /* xShmGet */
|
||||
tvfsShmRelease, /* xShmRelease */
|
||||
tvfsShmLock, /* xShmLock */
|
||||
tvfsShmClose /* xShmClose */
|
||||
};
|
||||
|
||||
/*
|
||||
** Close an tvfs-file.
|
||||
*/
|
||||
static int tvfsClose(sqlite3_file *pFile){
|
||||
tvfs_file *p = (tvfs_file *)pFile;
|
||||
TestvfsFile *p = (TestvfsFile *)pFile;
|
||||
if( p->pShmId ){
|
||||
Tcl_DecrRefCount(p->pShmId);
|
||||
p->pShmId = 0;
|
||||
}
|
||||
if( pFile->pMethods ){
|
||||
ckfree((char *)pFile->pMethods);
|
||||
}
|
||||
return sqlite3OsClose(p->pReal);
|
||||
}
|
||||
|
||||
@ -137,7 +151,7 @@ static int tvfsRead(
|
||||
int iAmt,
|
||||
sqlite_int64 iOfst
|
||||
){
|
||||
tvfs_file *p = (tvfs_file *)pFile;
|
||||
TestvfsFile *p = (TestvfsFile *)pFile;
|
||||
return sqlite3OsRead(p->pReal, zBuf, iAmt, iOfst);
|
||||
}
|
||||
|
||||
@ -150,7 +164,7 @@ static int tvfsWrite(
|
||||
int iAmt,
|
||||
sqlite_int64 iOfst
|
||||
){
|
||||
tvfs_file *p = (tvfs_file *)pFile;
|
||||
TestvfsFile *p = (TestvfsFile *)pFile;
|
||||
return sqlite3OsWrite(p->pReal, zBuf, iAmt, iOfst);
|
||||
}
|
||||
|
||||
@ -158,7 +172,7 @@ static int tvfsWrite(
|
||||
** Truncate an tvfs-file.
|
||||
*/
|
||||
static int tvfsTruncate(sqlite3_file *pFile, sqlite_int64 size){
|
||||
tvfs_file *p = (tvfs_file *)pFile;
|
||||
TestvfsFile *p = (TestvfsFile *)pFile;
|
||||
return sqlite3OsTruncate(p->pReal, size);
|
||||
}
|
||||
|
||||
@ -166,7 +180,7 @@ static int tvfsTruncate(sqlite3_file *pFile, sqlite_int64 size){
|
||||
** Sync an tvfs-file.
|
||||
*/
|
||||
static int tvfsSync(sqlite3_file *pFile, int flags){
|
||||
tvfs_file *p = (tvfs_file *)pFile;
|
||||
TestvfsFile *p = (TestvfsFile *)pFile;
|
||||
return sqlite3OsSync(p->pReal, flags);
|
||||
}
|
||||
|
||||
@ -174,7 +188,7 @@ static int tvfsSync(sqlite3_file *pFile, int flags){
|
||||
** Return the current file-size of an tvfs-file.
|
||||
*/
|
||||
static int tvfsFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
|
||||
tvfs_file *p = (tvfs_file *)pFile;
|
||||
TestvfsFile *p = (TestvfsFile *)pFile;
|
||||
return sqlite3OsFileSize(p->pReal, pSize);
|
||||
}
|
||||
|
||||
@ -182,7 +196,7 @@ static int tvfsFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
|
||||
** Lock an tvfs-file.
|
||||
*/
|
||||
static int tvfsLock(sqlite3_file *pFile, int eLock){
|
||||
tvfs_file *p = (tvfs_file *)pFile;
|
||||
TestvfsFile *p = (TestvfsFile *)pFile;
|
||||
return sqlite3OsLock(p->pReal, eLock);
|
||||
}
|
||||
|
||||
@ -190,7 +204,7 @@ static int tvfsLock(sqlite3_file *pFile, int eLock){
|
||||
** Unlock an tvfs-file.
|
||||
*/
|
||||
static int tvfsUnlock(sqlite3_file *pFile, int eLock){
|
||||
tvfs_file *p = (tvfs_file *)pFile;
|
||||
TestvfsFile *p = (TestvfsFile *)pFile;
|
||||
return sqlite3OsUnlock(p->pReal, eLock);
|
||||
}
|
||||
|
||||
@ -198,7 +212,7 @@ static int tvfsUnlock(sqlite3_file *pFile, int eLock){
|
||||
** Check if another file-handle holds a RESERVED lock on an tvfs-file.
|
||||
*/
|
||||
static int tvfsCheckReservedLock(sqlite3_file *pFile, int *pResOut){
|
||||
tvfs_file *p = (tvfs_file *)pFile;
|
||||
TestvfsFile *p = (TestvfsFile *)pFile;
|
||||
return sqlite3OsCheckReservedLock(p->pReal, pResOut);
|
||||
}
|
||||
|
||||
@ -206,7 +220,7 @@ static int tvfsCheckReservedLock(sqlite3_file *pFile, int *pResOut){
|
||||
** File control method. For custom operations on an tvfs-file.
|
||||
*/
|
||||
static int tvfsFileControl(sqlite3_file *pFile, int op, void *pArg){
|
||||
tvfs_file *p = (tvfs_file *)pFile;
|
||||
TestvfsFile *p = (TestvfsFile *)pFile;
|
||||
return sqlite3OsFileControl(p->pReal, op, pArg);
|
||||
}
|
||||
|
||||
@ -214,7 +228,7 @@ static int tvfsFileControl(sqlite3_file *pFile, int op, void *pArg){
|
||||
** Return the sector-size in bytes for an tvfs-file.
|
||||
*/
|
||||
static int tvfsSectorSize(sqlite3_file *pFile){
|
||||
tvfs_file *p = (tvfs_file *)pFile;
|
||||
TestvfsFile *p = (TestvfsFile *)pFile;
|
||||
return sqlite3OsSectorSize(p->pReal);
|
||||
}
|
||||
|
||||
@ -222,7 +236,7 @@ static int tvfsSectorSize(sqlite3_file *pFile){
|
||||
** Return the device characteristic flags supported by an tvfs-file.
|
||||
*/
|
||||
static int tvfsDeviceCharacteristics(sqlite3_file *pFile){
|
||||
tvfs_file *p = (tvfs_file *)pFile;
|
||||
TestvfsFile *p = (TestvfsFile *)pFile;
|
||||
return sqlite3OsDeviceCharacteristics(p->pReal);
|
||||
}
|
||||
|
||||
@ -237,12 +251,28 @@ static int tvfsOpen(
|
||||
int *pOutFlags
|
||||
){
|
||||
int rc;
|
||||
tvfs_file *p = (tvfs_file *)pFile;
|
||||
TestvfsFile *p = (TestvfsFile *)pFile;
|
||||
p->pShm = 0;
|
||||
p->pShmId = 0;
|
||||
p->zFilename = zName;
|
||||
p->pVfs = pVfs;
|
||||
p->pReal = (sqlite3_file *)&p[1];
|
||||
rc = sqlite3OsOpen(PARENTVFS(pVfs), zName, p->pReal, flags, pOutFlags);
|
||||
if( p->pReal->pMethods ){
|
||||
pFile->pMethods = &tvfs_io_methods;
|
||||
sqlite3_io_methods *pMethods;
|
||||
pMethods = (sqlite3_io_methods *)ckalloc(sizeof(sqlite3_io_methods));
|
||||
memcpy(pMethods, &tvfs_io_methods, sizeof(sqlite3_io_methods));
|
||||
if( ((Testvfs *)pVfs->pAppData)->isNoshm ){
|
||||
pMethods->xShmOpen = 0;
|
||||
pMethods->xShmGet = 0;
|
||||
pMethods->xShmSize = 0;
|
||||
pMethods->xShmRelease = 0;
|
||||
pMethods->xShmClose = 0;
|
||||
pMethods->xShmLock = 0;
|
||||
}
|
||||
pFile->pMethods = pMethods;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
@ -337,8 +367,8 @@ static int tvfsCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){
|
||||
return PARENTVFS(pVfs)->xCurrentTime(PARENTVFS(pVfs), pTimeOut);
|
||||
}
|
||||
|
||||
static void tvfsGrowBuffer(TestvfsShm *pShm, int reqSize, int *pNewSize){
|
||||
TestvfsBuffer *pBuffer = pShm->pBuffer;
|
||||
static void tvfsGrowBuffer(TestvfsFile *pFd, int reqSize, int *pNewSize){
|
||||
TestvfsBuffer *pBuffer = pFd->pShm;
|
||||
if( reqSize>pBuffer->n ){
|
||||
pBuffer->a = (u8 *)ckrealloc((char *)pBuffer->a, reqSize);
|
||||
memset(&pBuffer->a[pBuffer->n], 0x55, reqSize-pBuffer->n);
|
||||
@ -405,15 +435,17 @@ static int tvfsResultCode(Testvfs *p, int *pRc){
|
||||
}
|
||||
|
||||
static int tvfsShmOpen(
|
||||
sqlite3_vfs *pVfs,
|
||||
const char *zName,
|
||||
sqlite3_shm **pp
|
||||
sqlite3_file *pFileDes
|
||||
){
|
||||
Testvfs *p = (Testvfs *)(pVfs->pAppData);
|
||||
Testvfs *p;
|
||||
int rc = SQLITE_OK; /* Return code */
|
||||
Tcl_Obj *pId = 0; /* Id for this connection */
|
||||
TestvfsBuffer *pBuffer; /* Buffer to open connection to */
|
||||
TestvfsShm *pShm; /* New shm handle */
|
||||
TestvfsFile *pFd; /* The testvfs file structure */
|
||||
|
||||
pFd = (TestvfsFile*)pFileDes;
|
||||
p = (Testvfs *)pFd->pVfs->pAppData;
|
||||
assert( pFd->pShmId==0 && pFd->pShm==0 );
|
||||
|
||||
/* Evaluate the Tcl script:
|
||||
**
|
||||
@ -424,7 +456,7 @@ static int tvfsShmOpen(
|
||||
** connection is named "anon". Otherwise, the value returned by the
|
||||
** script is used as the connection name.
|
||||
*/
|
||||
tvfsExecTcl(p, "xShmOpen", Tcl_NewStringObj(zName, -1), 0, 0);
|
||||
tvfsExecTcl(p, "xShmOpen", Tcl_NewStringObj(pFd->zFilename, -1), 0, 0);
|
||||
if( tvfsResultCode(p, &rc) ){
|
||||
if( rc!=SQLITE_OK ) return rc;
|
||||
pId = Tcl_NewStringObj("anon", -1);
|
||||
@ -432,82 +464,75 @@ static int tvfsShmOpen(
|
||||
pId = Tcl_GetObjResult(p->interp);
|
||||
}
|
||||
Tcl_IncrRefCount(pId);
|
||||
|
||||
/* Allocate the TestvfsShm handle. */
|
||||
pShm = (TestvfsShm *)ckalloc(sizeof(TestvfsShm));
|
||||
memset(pShm, 0, sizeof(TestvfsShm));
|
||||
pShm->id = pId;
|
||||
pFd->pShmId = pId;
|
||||
|
||||
/* Search for a TestvfsBuffer. Create a new one if required. */
|
||||
for(pBuffer=p->pBuffer; pBuffer; pBuffer=pBuffer->pNext){
|
||||
if( 0==strcmp(zName, pBuffer->zFile) ) break;
|
||||
if( 0==strcmp(pFd->zFilename, pBuffer->zFile) ) break;
|
||||
}
|
||||
if( !pBuffer ){
|
||||
int nByte = sizeof(TestvfsBuffer) + strlen(zName) + 1;
|
||||
int nByte = sizeof(TestvfsBuffer) + strlen(pFd->zFilename) + 1;
|
||||
pBuffer = (TestvfsBuffer *)ckalloc(nByte);
|
||||
memset(pBuffer, 0, nByte);
|
||||
pBuffer->zFile = (char *)&pBuffer[1];
|
||||
strcpy(pBuffer->zFile, zName);
|
||||
strcpy(pBuffer->zFile, pFd->zFilename);
|
||||
pBuffer->pNext = p->pBuffer;
|
||||
p->pBuffer = pBuffer;
|
||||
}
|
||||
|
||||
/* Connect the TestvfsBuffer to the new TestvfsShm handle and return. */
|
||||
pBuffer->nRef++;
|
||||
pShm->pBuffer = pBuffer;
|
||||
*pp = (sqlite3_shm *)pShm;
|
||||
pFd->pShm = pBuffer;
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
static int tvfsShmSize(
|
||||
sqlite3_vfs *pVfs,
|
||||
sqlite3_shm *pShmHandle,
|
||||
sqlite3_file *pFile,
|
||||
int reqSize,
|
||||
int *pNewSize
|
||||
){
|
||||
int rc = SQLITE_OK;
|
||||
Testvfs *p = (Testvfs *)(pVfs->pAppData);
|
||||
TestvfsShm *pShm = (TestvfsShm *)pShmHandle;
|
||||
TestvfsFile *pFd = (TestvfsFile *)pFile;
|
||||
Testvfs *p = (Testvfs *)(pFd->pVfs->pAppData);
|
||||
|
||||
tvfsExecTcl(p, "xShmSize",
|
||||
Tcl_NewStringObj(pShm->pBuffer->zFile, -1), pShm->id, 0
|
||||
Tcl_NewStringObj(pFd->pShm->zFile, -1), pFd->pShmId, 0
|
||||
);
|
||||
tvfsResultCode(p, &rc);
|
||||
if( rc==SQLITE_OK ){
|
||||
tvfsGrowBuffer(pShm, reqSize, pNewSize);
|
||||
tvfsGrowBuffer(pFd, reqSize, pNewSize);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int tvfsShmGet(
|
||||
sqlite3_vfs *pVfs,
|
||||
sqlite3_shm *pShmHandle,
|
||||
sqlite3_file *pFile,
|
||||
int reqMapSize,
|
||||
int *pMapSize,
|
||||
void **pp
|
||||
){
|
||||
int rc = SQLITE_OK;
|
||||
Testvfs *p = (Testvfs *)(pVfs->pAppData);
|
||||
TestvfsShm *pShm = (TestvfsShm *)pShmHandle;
|
||||
TestvfsFile *pFd = (TestvfsFile *)pFile;
|
||||
Testvfs *p = (Testvfs *)(pFd->pVfs->pAppData);
|
||||
|
||||
tvfsExecTcl(p, "xShmGet",
|
||||
Tcl_NewStringObj(pShm->pBuffer->zFile, -1), pShm->id, 0
|
||||
Tcl_NewStringObj(pFd->pShm->zFile, -1), pFd->pShmId, 0
|
||||
);
|
||||
tvfsResultCode(p, &rc);
|
||||
if( rc==SQLITE_OK ){
|
||||
tvfsGrowBuffer(pShm, reqMapSize, pMapSize);
|
||||
*pp = pShm->pBuffer->a;
|
||||
tvfsGrowBuffer(pFd, reqMapSize, pMapSize);
|
||||
*pp = pFd->pShm->a;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int tvfsShmRelease(sqlite3_vfs *pVfs, sqlite3_shm *pShmHandle){
|
||||
static int tvfsShmRelease(sqlite3_file *pFile){
|
||||
int rc = SQLITE_OK;
|
||||
Testvfs *p = (Testvfs *)(pVfs->pAppData);
|
||||
TestvfsShm *pShm = (TestvfsShm *)pShmHandle;
|
||||
TestvfsFile *pFd = (TestvfsFile *)pFile;
|
||||
Testvfs *p = (Testvfs *)(pFd->pVfs->pAppData);
|
||||
|
||||
tvfsExecTcl(p, "xShmRelease",
|
||||
Tcl_NewStringObj(pShm->pBuffer->zFile, -1), pShm->id, 0
|
||||
Tcl_NewStringObj(pFd->pShm->zFile, -1), pFd->pShmId, 0
|
||||
);
|
||||
tvfsResultCode(p, &rc);
|
||||
|
||||
@ -515,14 +540,13 @@ static int tvfsShmRelease(sqlite3_vfs *pVfs, sqlite3_shm *pShmHandle){
|
||||
}
|
||||
|
||||
static int tvfsShmLock(
|
||||
sqlite3_vfs *pVfs,
|
||||
sqlite3_shm *pShmHandle,
|
||||
sqlite3_file *pFile,
|
||||
int desiredLock,
|
||||
int *gotLock
|
||||
){
|
||||
int rc = SQLITE_OK;
|
||||
Testvfs *p = (Testvfs *)(pVfs->pAppData);
|
||||
TestvfsShm *pShm = (TestvfsShm *)pShmHandle;
|
||||
TestvfsFile *pFd = (TestvfsFile *)pFile;
|
||||
Testvfs *p = (Testvfs *)(pFd->pVfs->pAppData);
|
||||
char *zLock = "";
|
||||
|
||||
switch( desiredLock ){
|
||||
@ -534,7 +558,7 @@ static int tvfsShmLock(
|
||||
case SQLITE_SHM_UNLOCK: zLock = "UNLOCK"; break;
|
||||
}
|
||||
tvfsExecTcl(p, "xShmLock",
|
||||
Tcl_NewStringObj(pShm->pBuffer->zFile, -1), pShm->id,
|
||||
Tcl_NewStringObj(pFd->pShm->zFile, -1), pFd->pShmId,
|
||||
Tcl_NewStringObj(zLock, -1)
|
||||
);
|
||||
tvfsResultCode(p, &rc);
|
||||
@ -546,21 +570,21 @@ static int tvfsShmLock(
|
||||
}
|
||||
|
||||
static int tvfsShmClose(
|
||||
sqlite3_vfs *pVfs,
|
||||
sqlite3_shm *pShmHandle,
|
||||
sqlite3_file *pFile,
|
||||
int deleteFlag
|
||||
){
|
||||
int rc = SQLITE_OK;
|
||||
Testvfs *p = (Testvfs *)(pVfs->pAppData);
|
||||
TestvfsShm *pShm = (TestvfsShm *)pShmHandle;
|
||||
TestvfsBuffer *pBuffer = pShm->pBuffer;
|
||||
TestvfsFile *pFd = (TestvfsFile *)pFile;
|
||||
Testvfs *p = (Testvfs *)(pFd->pVfs->pAppData);
|
||||
TestvfsBuffer *pBuffer = pFd->pShm;
|
||||
|
||||
assert( pFd->pShmId && pFd->pShm );
|
||||
#if 0
|
||||
assert( (deleteFlag!=0)==(pBuffer->nRef==1) );
|
||||
#endif
|
||||
|
||||
tvfsExecTcl(p, "xShmClose",
|
||||
Tcl_NewStringObj(pShm->pBuffer->zFile, -1), pShm->id, 0
|
||||
Tcl_NewStringObj(pFd->pShm->zFile, -1), pFd->pShmId, 0
|
||||
);
|
||||
tvfsResultCode(p, &rc);
|
||||
|
||||
@ -572,8 +596,9 @@ static int tvfsShmClose(
|
||||
ckfree((char *)pBuffer->a);
|
||||
ckfree((char *)pBuffer);
|
||||
}
|
||||
Tcl_DecrRefCount(pShm->id);
|
||||
ckfree((char *)pShm);
|
||||
Tcl_DecrRefCount(pFd->pShmId);
|
||||
pFd->pShmId = 0;
|
||||
pFd->pShm = 0;
|
||||
|
||||
return rc;
|
||||
}
|
||||
@ -687,10 +712,9 @@ static int testvfs_cmd(
|
||||
int objc,
|
||||
Tcl_Obj *CONST objv[]
|
||||
){
|
||||
|
||||
static sqlite3_vfs tvfs_vfs = {
|
||||
2, /* iVersion */
|
||||
sizeof(tvfs_file), /* szOsFile */
|
||||
sizeof(TestvfsFile), /* szOsFile */
|
||||
0, /* mxPathname */
|
||||
0, /* pNext */
|
||||
0, /* zName */
|
||||
@ -714,12 +738,6 @@ static int testvfs_cmd(
|
||||
tvfsSleep, /* xSleep */
|
||||
tvfsCurrentTime, /* xCurrentTime */
|
||||
0, /* xGetLastError */
|
||||
tvfsShmOpen,
|
||||
tvfsShmSize,
|
||||
tvfsShmGet,
|
||||
tvfsShmRelease,
|
||||
tvfsShmLock,
|
||||
tvfsShmClose,
|
||||
0,
|
||||
0,
|
||||
};
|
||||
@ -770,14 +788,7 @@ static int testvfs_cmd(
|
||||
pVfs->mxPathname = p->pParent->mxPathname;
|
||||
pVfs->szOsFile += p->pParent->szOsFile;
|
||||
p->pVfs = pVfs;
|
||||
if( isNoshm ){
|
||||
pVfs->xShmOpen = 0;
|
||||
pVfs->xShmGet = 0;
|
||||
pVfs->xShmSize = 0;
|
||||
pVfs->xShmRelease = 0;
|
||||
pVfs->xShmClose = 0;
|
||||
pVfs->xShmLock = 0;
|
||||
}
|
||||
p->isNoshm = isNoshm;
|
||||
|
||||
Tcl_CreateObjCommand(interp, zVfs, testvfs_obj_cmd, p, testvfs_obj_del);
|
||||
sqlite3_vfs_register(pVfs, 0);
|
||||
|
@ -5248,8 +5248,8 @@ case OP_JournalMode: { /* out2-prerelease */
|
||||
** in temporary storage or if the VFS does not support xShmOpen.
|
||||
*/
|
||||
if( eNew==PAGER_JOURNALMODE_WAL
|
||||
&& (zFilename[0]==0 /* Temp file */
|
||||
|| pVfs->iVersion<2 || pVfs->xShmOpen==0) /* No xShmOpen support */
|
||||
&& (zFilename[0]==0 /* Temp file */
|
||||
|| !sqlite3PagerWalSupported(pPager)) /* No xShmOpen support */
|
||||
){
|
||||
eNew = PAGER_JOURNALMODE_QUERY;
|
||||
}
|
||||
|
104
src/wal.c
104
src/wal.c
@ -125,16 +125,17 @@ struct WalIndexHdr {
|
||||
*/
|
||||
struct Wal {
|
||||
sqlite3_vfs *pVfs; /* The VFS used to create pFd */
|
||||
sqlite3_file *pFd; /* File handle for WAL file */
|
||||
sqlite3_file *pDbFd; /* File handle for the database file */
|
||||
sqlite3_file *pWalFd; /* File handle for WAL file */
|
||||
u32 iCallback; /* Value to pass to log callback (or 0) */
|
||||
sqlite3_shm *pWIndex; /* The open wal-index file */
|
||||
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 */
|
||||
u8 exclusiveMode; /* Non-zero if connection is in exclusive mode */
|
||||
u8 isWindexOpen; /* True if ShmOpen() called on pDbFd */
|
||||
WalIndexHdr hdr; /* Wal-index for current snapshot */
|
||||
char *zName; /* Name of underlying storage */
|
||||
char *zWalName; /* Name of WAL file */
|
||||
};
|
||||
|
||||
|
||||
@ -223,7 +224,7 @@ static int walSetLock(Wal *pWal, int desiredStatus){
|
||||
pWal->lockState = desiredStatus;
|
||||
}else{
|
||||
int got = pWal->lockState;
|
||||
rc = pWal->pVfs->xShmLock(pWal->pVfs, pWal->pWIndex, desiredStatus, &got);
|
||||
rc = sqlite3OsShmLock(pWal->pDbFd, desiredStatus, &got);
|
||||
pWal->lockState = got;
|
||||
if( got==SQLITE_SHM_READ_FULL || got==SQLITE_SHM_READ ){
|
||||
pWal->readerType = got;
|
||||
@ -404,7 +405,7 @@ static int walMappingSize(u32 iFrame){
|
||||
*/
|
||||
static void walIndexUnmap(Wal *pWal){
|
||||
if( pWal->pWiData ){
|
||||
pWal->pVfs->xShmRelease(pWal->pVfs, pWal->pWIndex);
|
||||
sqlite3OsShmRelease(pWal->pDbFd);
|
||||
pWal->pWiData = 0;
|
||||
}
|
||||
}
|
||||
@ -418,8 +419,8 @@ static void walIndexUnmap(Wal *pWal){
|
||||
static int walIndexMap(Wal *pWal, int reqSize){
|
||||
int rc = SQLITE_OK;
|
||||
if( pWal->pWiData==0 || reqSize>pWal->szWIndex ){
|
||||
rc = pWal->pVfs->xShmGet(pWal->pVfs, pWal->pWIndex, reqSize,
|
||||
&pWal->szWIndex, (void**)(char*)&pWal->pWiData);
|
||||
rc = sqlite3OsShmGet(pWal->pDbFd, reqSize, &pWal->szWIndex,
|
||||
(void**)(char*)&pWal->pWiData);
|
||||
if( rc==SQLITE_OK && pWal->pWiData==0 ){
|
||||
/* Make sure pWal->pWiData is not NULL while we are holding the
|
||||
** lock on the mapping. */
|
||||
@ -443,7 +444,7 @@ static int walIndexMap(Wal *pWal, int reqSize){
|
||||
static int walIndexRemap(Wal *pWal, int enlargeTo){
|
||||
int rc;
|
||||
int sz;
|
||||
rc = pWal->pVfs->xShmSize(pWal->pVfs, pWal->pWIndex, enlargeTo, &sz);
|
||||
rc = sqlite3OsShmSize(pWal->pDbFd, enlargeTo, &sz);
|
||||
if( rc==SQLITE_OK && sz>pWal->szWIndex ){
|
||||
walIndexUnmap(pWal);
|
||||
rc = walIndexMap(pWal, sz);
|
||||
@ -561,7 +562,7 @@ static int walIndexRecover(Wal *pWal){
|
||||
assert( pWal->lockState>SQLITE_SHM_READ );
|
||||
memset(&hdr, 0, sizeof(hdr));
|
||||
|
||||
rc = sqlite3OsFileSize(pWal->pFd, &nSize);
|
||||
rc = sqlite3OsFileSize(pWal->pWalFd, &nSize);
|
||||
if( rc!=SQLITE_OK ){
|
||||
return rc;
|
||||
}
|
||||
@ -579,7 +580,7 @@ static int walIndexRecover(Wal *pWal){
|
||||
/* Read in the first frame header in the file (to determine the
|
||||
** database page size).
|
||||
*/
|
||||
rc = sqlite3OsRead(pWal->pFd, aBuf, WAL_HDRSIZE, 0);
|
||||
rc = sqlite3OsRead(pWal->pWalFd, aBuf, WAL_HDRSIZE, 0);
|
||||
if( rc!=SQLITE_OK ){
|
||||
return rc;
|
||||
}
|
||||
@ -610,7 +611,7 @@ static int walIndexRecover(Wal *pWal){
|
||||
int isValid; /* True if this frame is valid */
|
||||
|
||||
/* Read and decode the next log frame. */
|
||||
rc = sqlite3OsRead(pWal->pFd, aFrame, nFrame, iOffset);
|
||||
rc = sqlite3OsRead(pWal->pWalFd, aFrame, nFrame, iOffset);
|
||||
if( rc!=SQLITE_OK ) break;
|
||||
isValid = walDecodeFrame(aCksum, &pgno, &nTruncate, nPgsz, aData, aFrame);
|
||||
if( !isValid ) break;
|
||||
@ -648,12 +649,11 @@ finished:
|
||||
** Close an open wal-index.
|
||||
*/
|
||||
static void walIndexClose(Wal *pWal, int isDelete){
|
||||
sqlite3_shm *pWIndex = pWal->pWIndex;
|
||||
if( pWIndex ){
|
||||
sqlite3_vfs *pVfs = pWal->pVfs;
|
||||
if( pWal->isWindexOpen ){
|
||||
int notUsed;
|
||||
pVfs->xShmLock(pVfs, pWIndex, SQLITE_SHM_UNLOCK, ¬Used);
|
||||
pVfs->xShmClose(pVfs, pWIndex, isDelete);
|
||||
sqlite3OsShmLock(pWal->pDbFd, SQLITE_SHM_UNLOCK, ¬Used);
|
||||
sqlite3OsShmClose(pWal->pDbFd, isDelete);
|
||||
pWal->isWindexOpen = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -675,41 +675,44 @@ static void walIndexClose(Wal *pWal, int isDelete){
|
||||
*/
|
||||
int sqlite3WalOpen(
|
||||
sqlite3_vfs *pVfs, /* vfs module to open wal and wal-index */
|
||||
const char *zDb, /* Name of database file */
|
||||
sqlite3_file *pDbFd, /* The open database file */
|
||||
const char *zDbName, /* Name of the database file */
|
||||
Wal **ppWal /* OUT: Allocated Wal handle */
|
||||
){
|
||||
int rc; /* Return Code */
|
||||
Wal *pRet; /* Object to allocate and return */
|
||||
int flags; /* Flags passed to OsOpen() */
|
||||
char *zWal; /* Path to WAL file */
|
||||
char *zWal; /* Name of write-ahead log file */
|
||||
int nWal; /* Length of zWal in bytes */
|
||||
|
||||
assert( zDb );
|
||||
if( pVfs->xShmOpen==0 ) return SQLITE_CANTOPEN_BKPT;
|
||||
assert( zDbName && zDbName[0] );
|
||||
assert( pDbFd );
|
||||
|
||||
/* Allocate an instance of struct Wal to return. */
|
||||
*ppWal = 0;
|
||||
nWal = strlen(zDb);
|
||||
pRet = (Wal*)sqlite3MallocZero(sizeof(Wal) + pVfs->szOsFile + nWal+5);
|
||||
nWal = sqlite3Strlen30(zDbName) + 5;
|
||||
pRet = (Wal*)sqlite3MallocZero(sizeof(Wal) + pVfs->szOsFile + nWal);
|
||||
if( !pRet ){
|
||||
return SQLITE_NOMEM;
|
||||
}
|
||||
|
||||
pRet->pVfs = pVfs;
|
||||
pRet->pFd = (sqlite3_file *)&pRet[1];
|
||||
pRet->zName = zWal = pVfs->szOsFile + (char*)pRet->pFd;
|
||||
sqlite3_snprintf(nWal+5, zWal, "%s-wal", zDb);
|
||||
rc = pVfs->xShmOpen(pVfs, zDb, &pRet->pWIndex);
|
||||
pRet->pWalFd = (sqlite3_file *)&pRet[1];
|
||||
pRet->pDbFd = pDbFd;
|
||||
pRet->zWalName = zWal = pVfs->szOsFile + (char*)pRet->pWalFd;
|
||||
sqlite3_snprintf(nWal, zWal, "%s-wal", zDbName);
|
||||
rc = sqlite3OsShmOpen(pDbFd);
|
||||
|
||||
/* Open file handle on the write-ahead log file. */
|
||||
if( rc==SQLITE_OK ){
|
||||
pRet->isWindexOpen = 1;
|
||||
flags = (SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|SQLITE_OPEN_MAIN_JOURNAL);
|
||||
rc = sqlite3OsOpen(pVfs, zWal, pRet->pFd, flags, &flags);
|
||||
rc = sqlite3OsOpen(pVfs, zWal, pRet->pWalFd, flags, &flags);
|
||||
}
|
||||
|
||||
if( rc!=SQLITE_OK ){
|
||||
walIndexClose(pRet, 0);
|
||||
sqlite3OsClose(pRet->pFd);
|
||||
sqlite3OsClose(pRet->pWalFd);
|
||||
sqlite3_free(pRet);
|
||||
}else{
|
||||
*ppWal = pRet;
|
||||
@ -809,7 +812,6 @@ static void walIteratorFree(WalIterator *p){
|
||||
*/
|
||||
static int walCheckpoint(
|
||||
Wal *pWal, /* Wal connection */
|
||||
sqlite3_file *pFd, /* File descriptor open on db file */
|
||||
int sync_flags, /* Flags for OsSync() (or 0) */
|
||||
int nBuf, /* Size of zBuf in bytes */
|
||||
u8 *zBuf /* Temporary buffer to use */
|
||||
@ -833,27 +835,27 @@ static int walCheckpoint(
|
||||
|
||||
/* Sync the log file to disk */
|
||||
if( sync_flags ){
|
||||
rc = sqlite3OsSync(pWal->pFd, sync_flags);
|
||||
rc = sqlite3OsSync(pWal->pWalFd, sync_flags);
|
||||
if( rc!=SQLITE_OK ) goto out;
|
||||
}
|
||||
|
||||
/* Iterate through the contents of the log, copying data to the db file. */
|
||||
while( 0==walIteratorNext(pIter, &iDbpage, &iFrame) ){
|
||||
rc = sqlite3OsRead(pWal->pFd, zBuf, pgsz,
|
||||
rc = sqlite3OsRead(pWal->pWalFd, zBuf, pgsz,
|
||||
walFrameOffset(iFrame, pgsz) + WAL_FRAME_HDRSIZE
|
||||
);
|
||||
if( rc!=SQLITE_OK ) goto out;
|
||||
rc = sqlite3OsWrite(pFd, zBuf, pgsz, (iDbpage-1)*pgsz);
|
||||
rc = sqlite3OsWrite(pWal->pDbFd, zBuf, pgsz, (iDbpage-1)*pgsz);
|
||||
if( rc!=SQLITE_OK ) goto out;
|
||||
}
|
||||
|
||||
/* Truncate the database file */
|
||||
rc = sqlite3OsTruncate(pFd, ((i64)pWal->hdr.nPage*(i64)pgsz));
|
||||
rc = sqlite3OsTruncate(pWal->pDbFd, ((i64)pWal->hdr.nPage*(i64)pgsz));
|
||||
if( rc!=SQLITE_OK ) goto out;
|
||||
|
||||
/* Sync the database file. If successful, update the wal-index. */
|
||||
if( sync_flags ){
|
||||
rc = sqlite3OsSync(pFd, sync_flags);
|
||||
rc = sqlite3OsSync(pWal->pDbFd, sync_flags);
|
||||
if( rc!=SQLITE_OK ) goto out;
|
||||
}
|
||||
pWal->hdr.iLastPg = 0;
|
||||
@ -876,9 +878,9 @@ static int walCheckpoint(
|
||||
*/
|
||||
#if 0
|
||||
memset(zBuf, 0, WAL_FRAME_HDRSIZE);
|
||||
rc = sqlite3OsWrite(pWal->pFd, zBuf, WAL_FRAME_HDRSIZE, 0);
|
||||
rc = sqlite3OsWrite(pWal->pWalFd, zBuf, WAL_FRAME_HDRSIZE, 0);
|
||||
if( rc!=SQLITE_OK ) goto out;
|
||||
rc = sqlite3OsSync(pWal->pFd, pWal->sync_flags);
|
||||
rc = sqlite3OsSync(pWal->pWalFd, pWal->sync_flags);
|
||||
#endif
|
||||
|
||||
out:
|
||||
@ -891,7 +893,6 @@ static int walCheckpoint(
|
||||
*/
|
||||
int sqlite3WalClose(
|
||||
Wal *pWal, /* Wal to close */
|
||||
sqlite3_file *pFd, /* Database file */
|
||||
int sync_flags, /* Flags to pass to OsSync() (or 0) */
|
||||
int nBuf,
|
||||
u8 *zBuf /* Buffer of at least nBuf bytes */
|
||||
@ -908,9 +909,9 @@ int sqlite3WalClose(
|
||||
**
|
||||
** The EXCLUSIVE lock is not released before returning.
|
||||
*/
|
||||
rc = sqlite3OsLock(pFd, SQLITE_LOCK_EXCLUSIVE);
|
||||
rc = sqlite3OsLock(pWal->pDbFd, SQLITE_LOCK_EXCLUSIVE);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = sqlite3WalCheckpoint(pWal, pFd, sync_flags, nBuf, zBuf, 0, 0);
|
||||
rc = sqlite3WalCheckpoint(pWal, sync_flags, nBuf, zBuf, 0, 0);
|
||||
if( rc==SQLITE_OK ){
|
||||
isDelete = 1;
|
||||
}
|
||||
@ -918,9 +919,9 @@ int sqlite3WalClose(
|
||||
}
|
||||
|
||||
walIndexClose(pWal, isDelete);
|
||||
sqlite3OsClose(pWal->pFd);
|
||||
sqlite3OsClose(pWal->pWalFd);
|
||||
if( isDelete ){
|
||||
sqlite3OsDelete(pWal->pVfs, pWal->zName, 0);
|
||||
sqlite3OsDelete(pWal->pVfs, pWal->zWalName, 0);
|
||||
}
|
||||
sqlite3_free(pWal);
|
||||
}
|
||||
@ -1191,7 +1192,7 @@ int sqlite3WalRead(
|
||||
if( iRead ){
|
||||
i64 iOffset = walFrameOffset(iRead, pWal->hdr.pgsz) + WAL_FRAME_HDRSIZE;
|
||||
*pInWal = 1;
|
||||
return sqlite3OsRead(pWal->pFd, pOut, nOut, iOffset);
|
||||
return sqlite3OsRead(pWal->pWalFd, pOut, nOut, iOffset);
|
||||
}
|
||||
|
||||
*pInWal = 0;
|
||||
@ -1290,7 +1291,7 @@ int sqlite3WalSavepointUndo(Wal *pWal, u32 iFrame){
|
||||
pWal->hdr.iLastPg = iFrame;
|
||||
if( iFrame>0 ){
|
||||
i64 iOffset = walFrameOffset(iFrame, pWal->hdr.pgsz) + sizeof(u32)*2;
|
||||
rc = sqlite3OsRead(pWal->pFd, aCksum, sizeof(aCksum), iOffset);
|
||||
rc = sqlite3OsRead(pWal->pWalFd, aCksum, sizeof(aCksum), iOffset);
|
||||
pWal->hdr.iCheck1 = sqlite3Get4byte(&aCksum[0]);
|
||||
pWal->hdr.iCheck2 = sqlite3Get4byte(&aCksum[4]);
|
||||
}
|
||||
@ -1334,7 +1335,7 @@ int sqlite3WalFrames(
|
||||
sqlite3_randomness(8, &aFrame[4]);
|
||||
pWal->hdr.iCheck1 = sqlite3Get4byte(&aFrame[4]);
|
||||
pWal->hdr.iCheck2 = sqlite3Get4byte(&aFrame[8]);
|
||||
rc = sqlite3OsWrite(pWal->pFd, aFrame, WAL_HDRSIZE, 0);
|
||||
rc = sqlite3OsWrite(pWal->pWalFd, aFrame, WAL_HDRSIZE, 0);
|
||||
if( rc!=SQLITE_OK ){
|
||||
return rc;
|
||||
}
|
||||
@ -1353,13 +1354,13 @@ int sqlite3WalFrames(
|
||||
/* Populate and write the frame header */
|
||||
nDbsize = (isCommit && p->pDirty==0) ? nTruncate : 0;
|
||||
walEncodeFrame(aCksum, p->pgno, nDbsize, nPgsz, p->pData, aFrame);
|
||||
rc = sqlite3OsWrite(pWal->pFd, aFrame, sizeof(aFrame), iOffset);
|
||||
rc = sqlite3OsWrite(pWal->pWalFd, aFrame, sizeof(aFrame), iOffset);
|
||||
if( rc!=SQLITE_OK ){
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Write the page data */
|
||||
rc = sqlite3OsWrite(pWal->pFd, p->pData, nPgsz, iOffset + sizeof(aFrame));
|
||||
rc = sqlite3OsWrite(pWal->pWalFd, p->pData, nPgsz, iOffset + sizeof(aFrame));
|
||||
if( rc!=SQLITE_OK ){
|
||||
return rc;
|
||||
}
|
||||
@ -1368,7 +1369,7 @@ int sqlite3WalFrames(
|
||||
|
||||
/* Sync the log file if the 'isSync' flag was specified. */
|
||||
if( sync_flags ){
|
||||
i64 iSegment = sqlite3OsSectorSize(pWal->pFd);
|
||||
i64 iSegment = sqlite3OsSectorSize(pWal->pWalFd);
|
||||
i64 iOffset = walFrameOffset(iFrame+1, nPgsz);
|
||||
|
||||
assert( isCommit );
|
||||
@ -1379,13 +1380,13 @@ int sqlite3WalFrames(
|
||||
iSegment = (((iOffset+iSegment-1)/iSegment) * iSegment);
|
||||
while( iOffset<iSegment ){
|
||||
walEncodeFrame(aCksum,pLast->pgno,nTruncate,nPgsz,pLast->pData,aFrame);
|
||||
rc = sqlite3OsWrite(pWal->pFd, aFrame, sizeof(aFrame), iOffset);
|
||||
rc = sqlite3OsWrite(pWal->pWalFd, aFrame, sizeof(aFrame), iOffset);
|
||||
if( rc!=SQLITE_OK ){
|
||||
return rc;
|
||||
}
|
||||
|
||||
iOffset += WAL_FRAME_HDRSIZE;
|
||||
rc = sqlite3OsWrite(pWal->pFd, pLast->pData, nPgsz, iOffset);
|
||||
rc = sqlite3OsWrite(pWal->pWalFd, pLast->pData, nPgsz, iOffset);
|
||||
if( rc!=SQLITE_OK ){
|
||||
return rc;
|
||||
}
|
||||
@ -1393,7 +1394,7 @@ int sqlite3WalFrames(
|
||||
iOffset += nPgsz;
|
||||
}
|
||||
|
||||
rc = sqlite3OsSync(pWal->pFd, sync_flags);
|
||||
rc = sqlite3OsSync(pWal->pWalFd, sync_flags);
|
||||
}
|
||||
assert( pWal->pWiData==0 );
|
||||
|
||||
@ -1445,7 +1446,6 @@ int sqlite3WalFrames(
|
||||
*/
|
||||
int sqlite3WalCheckpoint(
|
||||
Wal *pWal, /* Wal connection */
|
||||
sqlite3_file *pFd, /* File descriptor open on db file */
|
||||
int sync_flags, /* Flags to sync db file with (or 0) */
|
||||
int nBuf, /* Size of temporary buffer */
|
||||
u8 *zBuf, /* Temporary buffer to use */
|
||||
@ -1479,7 +1479,7 @@ int sqlite3WalCheckpoint(
|
||||
/* Copy data from the log to the database file. */
|
||||
rc = walIndexReadHdr(pWal, &isChanged);
|
||||
if( rc==SQLITE_OK ){
|
||||
rc = walCheckpoint(pWal, pFd, sync_flags, nBuf, zBuf);
|
||||
rc = walCheckpoint(pWal, sync_flags, nBuf, zBuf);
|
||||
}
|
||||
if( isChanged ){
|
||||
/* If a new wal-index header was loaded before the checkpoint was
|
||||
|
@ -41,8 +41,8 @@
|
||||
typedef struct Wal Wal;
|
||||
|
||||
/* Open and close a connection to a write-ahead log. */
|
||||
int sqlite3WalOpen(sqlite3_vfs*, const char *zDb, Wal **ppWal);
|
||||
int sqlite3WalClose(Wal *pWal, sqlite3_file *pFd, int sync_flags, int, u8 *);
|
||||
int sqlite3WalOpen(sqlite3_vfs*, sqlite3_file*, const char *zName, Wal**);
|
||||
int sqlite3WalClose(Wal *pWal, int sync_flags, int, u8 *);
|
||||
|
||||
/* Used by readers to open (lock) and close (unlock) a snapshot. A
|
||||
** snapshot is like a read-transaction. It is the state of the database
|
||||
@ -81,7 +81,6 @@ int sqlite3WalFrames(Wal *pWal, int, PgHdr *, Pgno, int, int);
|
||||
/* Copy pages from the log to the database file */
|
||||
int sqlite3WalCheckpoint(
|
||||
Wal *pWal, /* Write-ahead log connection */
|
||||
sqlite3_file *pFd, /* File descriptor open on db file */
|
||||
int sync_flags, /* Flags to sync db file with (or 0) */
|
||||
int nBuf, /* Size of buffer nBuf */
|
||||
u8 *zBuf, /* Temporary buffer to use */
|
||||
|
Loading…
x
Reference in New Issue
Block a user