mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-08 14:02:16 +03:00
Experimental change to the xShmXXX parts of the VFS interface.
FossilOrigin-Name: ca68472db01c14a899892007d1cbaff5e86ae193
This commit is contained in:
130
src/test_vfs.c
130
src/test_vfs.c
@@ -75,10 +75,14 @@ struct Testvfs {
|
||||
#define TESTVFS_SHMLOCK_MASK 0x00000010
|
||||
#define TESTVFS_SHMBARRIER_MASK 0x00000020
|
||||
#define TESTVFS_SHMCLOSE_MASK 0x00000040
|
||||
#define TESTVFS_SHMPAGE_MASK 0x00000080
|
||||
|
||||
#define TESTVFS_OPEN_MASK 0x00000080
|
||||
#define TESTVFS_SYNC_MASK 0x00000100
|
||||
#define TESTVFS_ALL_MASK 0x000001FF
|
||||
#define TESTVFS_OPEN_MASK 0x00000100
|
||||
#define TESTVFS_SYNC_MASK 0x00000200
|
||||
#define TESTVFS_ALL_MASK 0x000003FF
|
||||
|
||||
|
||||
#define TESTVFS_MAX_PAGES 256
|
||||
|
||||
/*
|
||||
** A shared-memory buffer. There is one of these objects for each shared
|
||||
@@ -87,8 +91,8 @@ struct Testvfs {
|
||||
*/
|
||||
struct TestvfsBuffer {
|
||||
char *zFile; /* Associated file name */
|
||||
int n; /* Size of allocated buffer in bytes */
|
||||
u8 *a; /* Buffer allocated using ckalloc() */
|
||||
int pgsz; /* Page size */
|
||||
u8 *aPage[TESTVFS_MAX_PAGES]; /* Array of ckalloc'd pages */
|
||||
TestvfsFile *pFile; /* List of open handles */
|
||||
TestvfsBuffer *pNext; /* Next in linked list of all buffers */
|
||||
};
|
||||
@@ -139,6 +143,7 @@ static int tvfsShmRelease(sqlite3_file*);
|
||||
static int tvfsShmLock(sqlite3_file*, int , int, int);
|
||||
static void tvfsShmBarrier(sqlite3_file*);
|
||||
static int tvfsShmClose(sqlite3_file*, int);
|
||||
static int tvfsShmPage(sqlite3_file*,int,int,int, void volatile **);
|
||||
|
||||
static sqlite3_io_methods tvfs_io_methods = {
|
||||
2, /* iVersion */
|
||||
@@ -160,7 +165,8 @@ static sqlite3_io_methods tvfs_io_methods = {
|
||||
tvfsShmRelease, /* xShmRelease */
|
||||
tvfsShmLock, /* xShmLock */
|
||||
tvfsShmBarrier, /* xShmBarrier */
|
||||
tvfsShmClose /* xShmClose */
|
||||
tvfsShmClose, /* xShmClose */
|
||||
tvfsShmPage /* xShmPage */
|
||||
};
|
||||
|
||||
static int tvfsResultCode(Testvfs *p, int *pRc){
|
||||
@@ -547,16 +553,6 @@ static int tvfsCurrentTime(sqlite3_vfs *pVfs, double *pTimeOut){
|
||||
return PARENTVFS(pVfs)->xCurrentTime(PARENTVFS(pVfs), pTimeOut);
|
||||
}
|
||||
|
||||
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);
|
||||
pBuffer->n = reqSize;
|
||||
}
|
||||
*pNewSize = pBuffer->n;
|
||||
}
|
||||
|
||||
static int tvfsInjectIoerr(Testvfs *p){
|
||||
int ret = 0;
|
||||
if( p->ioerr ){
|
||||
@@ -624,66 +620,66 @@ static int tvfsShmSize(
|
||||
int reqSize,
|
||||
int *pNewSize
|
||||
){
|
||||
int rc = SQLITE_OK;
|
||||
TestvfsFile *pFd = (TestvfsFile *)pFile;
|
||||
Testvfs *p = (Testvfs *)(pFd->pVfs->pAppData);
|
||||
|
||||
if( p->pScript && p->mask&TESTVFS_SHMSIZE_MASK ){
|
||||
tvfsExecTcl(p, "xShmSize",
|
||||
Tcl_NewStringObj(pFd->pShm->zFile, -1), pFd->pShmId, 0
|
||||
);
|
||||
tvfsResultCode(p, &rc);
|
||||
}
|
||||
if( rc==SQLITE_OK && p->mask&TESTVFS_SHMSIZE_MASK && tvfsInjectIoerr(p) ){
|
||||
rc = SQLITE_IOERR;
|
||||
}
|
||||
if( rc==SQLITE_OK ){
|
||||
tvfsGrowBuffer(pFd, reqSize, pNewSize);
|
||||
}
|
||||
return rc;
|
||||
assert(0);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
static int tvfsShmGet(
|
||||
sqlite3_file *pFile,
|
||||
int reqMapSize,
|
||||
int *pMapSize,
|
||||
volatile void **pp
|
||||
){
|
||||
assert(0);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
static int tvfsShmRelease(sqlite3_file *pFile){
|
||||
assert(0);
|
||||
return SQLITE_OK;
|
||||
}
|
||||
|
||||
static void tvfsAllocPage(TestvfsBuffer *p, int iPage, int pgsz){
|
||||
assert( iPage<TESTVFS_MAX_PAGES );
|
||||
if( p->aPage[iPage]==0 ){
|
||||
p->aPage[iPage] = ckalloc(pgsz);
|
||||
memset(p->aPage[iPage], 0, pgsz);
|
||||
p->pgsz = pgsz;
|
||||
}
|
||||
}
|
||||
|
||||
static int tvfsShmPage(
|
||||
sqlite3_file *pFile, /* Handle open on database file */
|
||||
int iPage, /* Page to retrieve */
|
||||
int pgsz, /* Size of pages */
|
||||
int isWrite, /* True to extend file if necessary */
|
||||
void volatile **pp /* OUT: Mapped memory */
|
||||
){
|
||||
int rc = SQLITE_OK;
|
||||
TestvfsFile *pFd = (TestvfsFile *)pFile;
|
||||
Testvfs *p = (Testvfs *)(pFd->pVfs->pAppData);
|
||||
|
||||
if( p->pScript && p->mask&TESTVFS_SHMGET_MASK ){
|
||||
tvfsExecTcl(p, "xShmGet",
|
||||
Tcl_NewStringObj(pFd->pShm->zFile, -1), pFd->pShmId,
|
||||
Tcl_NewIntObj(reqMapSize)
|
||||
if( p->pScript && p->mask&TESTVFS_SHMPAGE_MASK ){
|
||||
Tcl_Obj *pArg = Tcl_NewObj();
|
||||
Tcl_ListObjAppendElement(p->interp, pArg, Tcl_NewIntObj(iPage));
|
||||
Tcl_ListObjAppendElement(p->interp, pArg, Tcl_NewIntObj(pgsz));
|
||||
Tcl_ListObjAppendElement(p->interp, pArg, Tcl_NewIntObj(isWrite));
|
||||
tvfsExecTcl(p, "xShmPage",
|
||||
Tcl_NewStringObj(pFd->pShm->zFile, -1), pFd->pShmId, pArg
|
||||
);
|
||||
tvfsResultCode(p, &rc);
|
||||
}
|
||||
if( rc==SQLITE_OK && p->mask&TESTVFS_SHMGET_MASK && tvfsInjectIoerr(p) ){
|
||||
if( rc==SQLITE_OK && p->mask&TESTVFS_SHMPAGE_MASK && tvfsInjectIoerr(p) ){
|
||||
rc = SQLITE_IOERR;
|
||||
}
|
||||
|
||||
*pMapSize = pFd->pShm->n;
|
||||
*pp = pFd->pShm->a;
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int tvfsShmRelease(sqlite3_file *pFile){
|
||||
int rc = SQLITE_OK;
|
||||
TestvfsFile *pFd = (TestvfsFile *)pFile;
|
||||
Testvfs *p = (Testvfs *)(pFd->pVfs->pAppData);
|
||||
|
||||
if( p->pScript && p->mask&TESTVFS_SHMRELEASE_MASK ){
|
||||
tvfsExecTcl(p, "xShmRelease",
|
||||
Tcl_NewStringObj(pFd->pShm->zFile, -1), pFd->pShmId, 0
|
||||
);
|
||||
tvfsResultCode(p, &rc);
|
||||
if( rc==SQLITE_OK && isWrite && !pFd->pShm->aPage[iPage] ){
|
||||
tvfsAllocPage(pFd->pShm, iPage, pgsz);
|
||||
}
|
||||
*pp = (void volatile *)pFd->pShm->aPage[iPage];
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
static int tvfsShmLock(
|
||||
sqlite3_file *pFile,
|
||||
int ofst,
|
||||
@@ -782,10 +778,13 @@ static int tvfsShmClose(
|
||||
*ppFd = pFd->pNext;
|
||||
|
||||
if( pBuffer->pFile==0 ){
|
||||
int i;
|
||||
TestvfsBuffer **pp;
|
||||
for(pp=&p->pBuffer; *pp!=pBuffer; pp=&((*pp)->pNext));
|
||||
*pp = (*pp)->pNext;
|
||||
ckfree((char *)pBuffer->a);
|
||||
for(i=0; pBuffer->aPage[i]; i++){
|
||||
ckfree((char *)pBuffer->aPage[i]);
|
||||
}
|
||||
ckfree((char *)pBuffer);
|
||||
}
|
||||
pFd->pShm = 0;
|
||||
@@ -821,6 +820,8 @@ static int testvfs_obj_cmd(
|
||||
|
||||
switch( (enum DB_enum)i ){
|
||||
case CMD_SHM: {
|
||||
Tcl_Obj *pObj;
|
||||
int i;
|
||||
TestvfsBuffer *pBuffer;
|
||||
char *zName;
|
||||
if( objc!=3 && objc!=4 ){
|
||||
@@ -838,11 +839,22 @@ static int testvfs_obj_cmd(
|
||||
if( objc==4 ){
|
||||
int n;
|
||||
u8 *a = Tcl_GetByteArrayFromObj(objv[3], &n);
|
||||
pBuffer->a = (u8 *)ckrealloc((char *)pBuffer->a, n);
|
||||
pBuffer->n = n;
|
||||
memcpy(pBuffer->a, a, n);
|
||||
assert( pBuffer->pgsz==0 || pBuffer->pgsz==32768 );
|
||||
for(i=0; i*32768<n; i++){
|
||||
int nByte = 32768;
|
||||
tvfsAllocPage(pBuffer, i, 32768);
|
||||
if( n-i*32768<32768 ){
|
||||
nByte = n;
|
||||
}
|
||||
memcpy(pBuffer->aPage[i], &a[i*32768], nByte);
|
||||
}
|
||||
}
|
||||
Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(pBuffer->a, pBuffer->n));
|
||||
|
||||
pObj = Tcl_NewObj();
|
||||
for(i=0; pBuffer->aPage[i]; i++){
|
||||
Tcl_AppendObjToObj(pObj, Tcl_NewByteArrayObj(pBuffer->aPage[i], 32768));
|
||||
}
|
||||
Tcl_SetObjResult(interp, pObj);
|
||||
break;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user