From 92c4b8a2cadfc742747b6c684950b56583671d43 Mon Sep 17 00:00:00 2001 From: danielk1977 Date: Mon, 15 Sep 2008 14:08:04 +0000 Subject: [PATCH] Modify test_async.c to avoid using internal SQLite APIs. There are still some comments that need updating. (CVS 5698) FossilOrigin-Name: 1d4fcaafd058bf1b726378e9ec308ecd8130fe1b --- manifest | 12 +- manifest.uuid | 2 +- src/test_async.c | 284 ++++++++++++++++++++++++++++------------------- 3 files changed, 175 insertions(+), 123 deletions(-) diff --git a/manifest b/manifest index fb4aba9179..ad8693a7d6 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Check\sif\serror\scode\sENOTSUP\sis\ssupported\sbefore\susing\sit.\sTicket\s#3375.\s(CVS\s5697) -D 2008-09-15T04:20:32 +C Modify\stest_async.c\sto\savoid\susing\sinternal\sSQLite\sAPIs.\sThere\sare\sstill\ssome\scomments\sthat\sneed\supdating.\s(CVS\s5698) +D 2008-09-15T14:08:04 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.in d15a7ebfe5e057a72a49805ffb302dbb601c8329 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -165,7 +165,7 @@ F src/test6.c 0a0304a69cfa4962a429d084c6d451ff9e4fb572 F src/test7.c 475b1fa7e3275408b40a3cbdc9508cbdc41ffa02 F src/test8.c 3637439424d0d21ff2dcf9b015c30fcc1e7bcb24 F src/test9.c 904ebe0ed1472d6bad17a81e2ecbfc20017dc237 -F src/test_async.c da9f58f49faccd3a26ba89f58de125862351b6e2 +F src/test_async.c 2f644e5c4ee4ecc568234a22b98d992deda6006e F src/test_autoext.c f53b0cdf7bf5f08100009572a5d65cdb540bd0ad F src/test_btree.c 8d5b835054f1dd15992e09864a8bc04386bab701 F src/test_config.c b2681a8e1b570f0c3686c934d6ef6112921af05d @@ -635,7 +635,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81 F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 1dbced29de5f59ba2ebf877edcadf171540374d1 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e -P ced6bbd228b4a324ddb9c5ff15fd027811c8806a -R 4d23aa13f9709d8ea8e494bd8ecff601 +P c32cb106c5d68e98f51f1eaf9ae0e2a3c36d00d6 +R 81c8df88182aeac4375b62d10daf76ae U danielk1977 -Z 15f69e2058d6662c1b75f3319378d24f +Z 598fdfba976b3753bad5428908262014 diff --git a/manifest.uuid b/manifest.uuid index 220e8fcf46..c1fb60e88d 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -c32cb106c5d68e98f51f1eaf9ae0e2a3c36d00d6 \ No newline at end of file +1d4fcaafd058bf1b726378e9ec308ecd8130fe1b \ No newline at end of file diff --git a/src/test_async.c b/src/test_async.c index 7b48afe0ae..d255d0dcd9 100644 --- a/src/test_async.c +++ b/src/test_async.c @@ -10,7 +10,7 @@ ** ************************************************************************* ** -** $Id: test_async.c,v 1.45 2008/06/26 10:41:19 danielk1977 Exp $ +** $Id: test_async.c,v 1.46 2008/09/15 14:08:04 danielk1977 Exp $ ** ** This file contains an example implementation of an asynchronous IO ** backend for SQLite. @@ -109,7 +109,9 @@ #define ENABLE_FILE_LOCKING #ifndef SQLITE_AMALGAMATION -# include "sqliteInt.h" +# include "sqlite3.h" +# include +# include #endif #include @@ -274,7 +276,7 @@ static struct TestAsyncStaticData { pthread_cond_t emptySignal; /* Notify when the write queue is empty */ AsyncWrite *pQueueFirst; /* Next write operation to be processed */ AsyncWrite *pQueueLast; /* Last write operation on the list */ - Hash aLock; /* Files locked */ + AsyncLock *pLock; /* Linked list of all AsyncLock structures */ volatile int ioDelay; /* Extra delay between write operations */ volatile int writerHaltWhenIdle; /* Writer thread halts when queue empty */ volatile int writerHaltNow; /* Writer thread halts after next op */ @@ -350,7 +352,7 @@ static const char *azOpcodeName[] = { struct AsyncWrite { AsyncFileData *pFileData; /* File to write data to or sync */ int op; /* One of ASYNC_xxx etc. */ - i64 iOffset; /* See above */ + sqlite_int64 iOffset; /* See above */ int nByte; /* See above */ char *zBuf; /* Data to write to file (or NULL if op!=ASYNC_WRITE) */ AsyncWrite *pNext; /* Next write operation (to any file) */ @@ -376,9 +378,12 @@ struct AsyncWrite { ** the implementation of database locking used by this backend. */ struct AsyncLock { + char *zFile; + int nFile; sqlite3_file *pFile; int eLock; AsyncFileLock *pList; + AsyncLock *pNext; /* Next in linked list headed by async.pLock */ }; /* @@ -412,7 +417,8 @@ struct AsyncFileData { int nName; /* Number of characters in zName */ sqlite3_file *pBaseRead; /* Read handle to the underlying Os file */ sqlite3_file *pBaseWrite; /* Write handle to the underlying Os file */ - AsyncFileLock lock; + AsyncFileLock lock; /* Lock state for this handle */ + AsyncLock *pLock; /* AsyncLock object for this file system entry */ AsyncWrite close; }; @@ -631,7 +637,7 @@ static void incrOpenFileCount(){ static int addNewAsyncWrite( AsyncFileData *pFileData, int op, - i64 iOffset, + sqlite3_int64 iOffset, int nByte, const char *zByte ){ @@ -686,7 +692,12 @@ static int asyncClose(sqlite3_file *pFile){ ** the global AsyncWrite list. Either SQLITE_OK or SQLITE_NOMEM may be ** returned. */ -static int asyncWrite(sqlite3_file *pFile, const void *pBuf, int amt, i64 iOff){ +static int asyncWrite( + sqlite3_file *pFile, + const void *pBuf, + int amt, + sqlite3_int64 iOff +){ AsyncFileData *p = ((AsyncFile *)pFile)->pData; return addNewAsyncWrite(p, ASYNC_WRITE, iOff, amt, pBuf); } @@ -698,10 +709,15 @@ static int asyncWrite(sqlite3_file *pFile, const void *pBuf, int amt, i64 iOff){ ** ** This method holds the mutex from start to finish. */ -static int asyncRead(sqlite3_file *pFile, void *zOut, int iAmt, i64 iOffset){ +static int asyncRead( + sqlite3_file *pFile, + void *zOut, + int iAmt, + sqlite3_int64 iOffset +){ AsyncFileData *p = ((AsyncFile *)pFile)->pData; int rc = SQLITE_OK; - i64 filesize; + sqlite3_int64 filesize; int nRead; sqlite3_file *pBase = p->pBaseRead; @@ -717,13 +733,13 @@ static int asyncRead(sqlite3_file *pFile, void *zOut, int iAmt, i64 iOffset){ } if( pBase->pMethods ){ - rc = sqlite3OsFileSize(pBase, &filesize); + rc = pBase->pMethods->xFileSize(pBase, &filesize); if( rc!=SQLITE_OK ){ goto asyncread_out; } nRead = MIN(filesize - iOffset, iAmt); if( nRead>0 ){ - rc = sqlite3OsRead(pBase, zOut, nRead, iOffset); + rc = pBase->pMethods->xRead(pBase, zOut, nRead, iOffset); ASYNC_TRACE(("READ %s %d bytes at %d\n", p->zName, nRead, iOffset)); } } @@ -733,7 +749,10 @@ static int asyncRead(sqlite3_file *pFile, void *zOut, int iAmt, i64 iOffset){ char *zName = p->zName; for(pWrite=async.pQueueFirst; pWrite; pWrite = pWrite->pNext){ - if( pWrite->op==ASYNC_WRITE && pWrite->pFileData->zName==zName ){ + if( pWrite->op==ASYNC_WRITE && ( + (pWrite->pFileData==p) || + (zName && pWrite->pFileData->zName==zName) + )){ int iBeginOut = (pWrite->iOffset-iOffset); int iBeginIn = -iBeginOut; int nCopy; @@ -759,7 +778,7 @@ asyncread_out: ** Truncate the file to nByte bytes in length. This just adds an entry to ** the write-op list, no IO actually takes place. */ -static int asyncTruncate(sqlite3_file *pFile, i64 nByte){ +static int asyncTruncate(sqlite3_file *pFile, sqlite3_int64 nByte){ AsyncFileData *p = ((AsyncFile *)pFile)->pData; return addNewAsyncWrite(p, ASYNC_TRUNCATE, nByte, 0, 0); } @@ -780,10 +799,10 @@ static int asyncSync(sqlite3_file *pFile, int flags){ ** ** This method holds the mutex from start to finish. */ -int asyncFileSize(sqlite3_file *pFile, i64 *piSize){ +int asyncFileSize(sqlite3_file *pFile, sqlite3_int64 *piSize){ AsyncFileData *p = ((AsyncFile *)pFile)->pData; int rc = SQLITE_OK; - i64 s = 0; + sqlite3_int64 s = 0; sqlite3_file *pBase; pthread_mutex_lock(&async.queueMutex); @@ -795,18 +814,24 @@ int asyncFileSize(sqlite3_file *pFile, i64 *piSize){ */ pBase = p->pBaseRead; if( pBase->pMethods ){ - rc = sqlite3OsFileSize(pBase, &s); + rc = pBase->pMethods->xFileSize(pBase, &s); } if( rc==SQLITE_OK ){ AsyncWrite *pWrite; for(pWrite=async.pQueueFirst; pWrite; pWrite = pWrite->pNext){ - if( pWrite->op==ASYNC_DELETE && strcmp(p->zName, pWrite->zBuf)==0 ){ + if( pWrite->op==ASYNC_DELETE + && p->zName + && strcmp(p->zName, pWrite->zBuf)==0 + ){ s = 0; - }else if( pWrite->pFileData && pWrite->pFileData->zName==p->zName){ + }else if( pWrite->pFileData && ( + (pWrite->pFileData==p) + || (p->zName && pWrite->pFileData->zName==p->zName) + )){ switch( pWrite->op ){ case ASYNC_WRITE: - s = MAX(pWrite->iOffset + (i64)(pWrite->nByte), s); + s = MAX(pWrite->iOffset + (sqlite3_int64)(pWrite->nByte), s); break; case ASYNC_TRUNCATE: s = MIN(s, pWrite->iOffset); @@ -838,13 +863,13 @@ static int getFileLock(AsyncLock *pLock){ } if( eRequired>pLock->eLock ){ - rc = sqlite3OsLock(pLock->pFile, eRequired); + rc = pLock->pFile->pMethods->xLock(pLock->pFile, eRequired); if( rc==SQLITE_OK ){ pLock->eLock = eRequired; } } else if( eRequiredeLock && eRequired<=SQLITE_LOCK_SHARED ){ - rc = sqlite3OsUnlock(pLock->pFile, eRequired); + rc = pLock->pFile->pMethods->xUnlock(pLock->pFile, eRequired); if( rc==SQLITE_OK ){ pLock->eLock = eRequired; } @@ -854,6 +879,19 @@ static int getFileLock(AsyncLock *pLock){ return rc; } +/* +** Return the AsyncLock structure from the global async.pLock list +** associated with the file-system entry identified by path zName +** (a string of nName bytes). If no such structure exists, return 0. +*/ +static AsyncLock *findLock(const char *zName, int nName){ + AsyncLock *p = async.pLock; + while( p && (p->nFile!=nName || memcmp(p->zFile, zName, nName)) ){ + p = p->pNext; + } + return p; +} + /* ** The following two methods - asyncLock() and asyncUnlock() - are used ** to obtain and release locks on database files opened with the @@ -863,43 +901,48 @@ static int asyncLock(sqlite3_file *pFile, int eLock){ int rc = SQLITE_OK; AsyncFileData *p = ((AsyncFile *)pFile)->pData; - pthread_mutex_lock(&async.lockMutex); - if( p->lock.eLockzName, p->nName); - assert(pLock && pLock->pList); - for(pIter=pLock->pList; pIter; pIter=pIter->pNext){ - if( pIter!=&p->lock && ( - (eLock==SQLITE_LOCK_EXCLUSIVE && pIter->eLock>=SQLITE_LOCK_SHARED) || - (eLock==SQLITE_LOCK_PENDING && pIter->eLock>=SQLITE_LOCK_RESERVED) || - (eLock==SQLITE_LOCK_RESERVED && pIter->eLock>=SQLITE_LOCK_RESERVED) || - (eLock==SQLITE_LOCK_SHARED && pIter->eLock>=SQLITE_LOCK_PENDING) - )){ - rc = SQLITE_BUSY; + if( p->zName ){ + pthread_mutex_lock(&async.lockMutex); + if( p->lock.eLockpLock; + AsyncFileLock *pIter; + assert(pLock && pLock->pList); + for(pIter=pLock->pList; pIter; pIter=pIter->pNext){ + if( pIter!=&p->lock && ( + (eLock==SQLITE_LOCK_EXCLUSIVE && pIter->eLock>=SQLITE_LOCK_SHARED) || + (eLock==SQLITE_LOCK_PENDING && pIter->eLock>=SQLITE_LOCK_RESERVED) || + (eLock==SQLITE_LOCK_RESERVED && pIter->eLock>=SQLITE_LOCK_RESERVED) || + (eLock==SQLITE_LOCK_SHARED && pIter->eLock>=SQLITE_LOCK_PENDING) + )){ + rc = SQLITE_BUSY; + } + } + if( rc==SQLITE_OK ){ + p->lock.eLock = eLock; + p->lock.eAsyncLock = MAX(p->lock.eAsyncLock, eLock); + } + assert(p->lock.eAsyncLock>=p->lock.eLock); + if( rc==SQLITE_OK ){ + rc = getFileLock(pLock); } } - if( rc==SQLITE_OK ){ - p->lock.eLock = eLock; - p->lock.eAsyncLock = MAX(p->lock.eAsyncLock, eLock); - } - assert(p->lock.eAsyncLock>=p->lock.eLock); - if( rc==SQLITE_OK ){ - rc = getFileLock(pLock); - } + pthread_mutex_unlock(&async.lockMutex); } - pthread_mutex_unlock(&async.lockMutex); ASYNC_TRACE(("LOCK %d (%s) rc=%d\n", eLock, p->zName, rc)); return rc; } static int asyncUnlock(sqlite3_file *pFile, int eLock){ + int rc = SQLITE_OK; AsyncFileData *p = ((AsyncFile *)pFile)->pData; - AsyncFileLock *pLock = &p->lock; - pthread_mutex_lock(&async.lockMutex); - pLock->eLock = MIN(pLock->eLock, eLock); - pthread_mutex_unlock(&async.lockMutex); - return addNewAsyncWrite(p, ASYNC_UNLOCK, 0, eLock, 0); + if( p->zName ){ + AsyncFileLock *pLock = &p->lock; + pthread_mutex_lock(&async.lockMutex); + pLock->eLock = MIN(pLock->eLock, eLock); + pthread_mutex_unlock(&async.lockMutex); + rc = addNewAsyncWrite(p, ASYNC_UNLOCK, 0, eLock, 0); + } + return rc; } /* @@ -909,12 +952,10 @@ static int asyncUnlock(sqlite3_file *pFile, int eLock){ static int asyncCheckReservedLock(sqlite3_file *pFile, int *pResOut){ int ret = 0; AsyncFileLock *pIter; - AsyncLock *pLock; AsyncFileData *p = ((AsyncFile *)pFile)->pData; pthread_mutex_lock(&async.lockMutex); - pLock = (AsyncLock *)sqlite3HashFind(&async.aLock, p->zName, p->nName); - for(pIter=pLock->pList; pIter; pIter=pIter->pNext){ + for(pIter=p->pLock->pList; pIter; pIter=pIter->pNext){ if( pIter->eLock>=SQLITE_LOCK_RESERVED ){ ret = 1; } @@ -927,7 +968,7 @@ static int asyncCheckReservedLock(sqlite3_file *pFile, int *pResOut){ } /* -** This is a no-op, as the asynchronous backend does not support locking. +** sqlite3_file_control() implementation. */ static int asyncFileControl(sqlite3_file *id, int op, void *pArg){ switch( op ){ @@ -954,28 +995,28 @@ static int asyncDeviceCharacteristics(sqlite3_file *pFile){ } static int unlinkAsyncFile(AsyncFileData *pData){ - AsyncLock *pLock; AsyncFileLock **ppIter; int rc = SQLITE_OK; - pLock = sqlite3HashFind(&async.aLock, pData->zName, pData->nName); - for(ppIter=&pLock->pList; *ppIter; ppIter=&((*ppIter)->pNext)){ - if( (*ppIter)==&pData->lock ){ - *ppIter = pData->lock.pNext; - break; - } - } - if( !pLock->pList ){ - if( pLock->pFile ){ - sqlite3OsClose(pLock->pFile); + if( pData->zName ){ + AsyncLock *pLock = pData->pLock; + for(ppIter=&pLock->pList; *ppIter; ppIter=&((*ppIter)->pNext)){ + if( (*ppIter)==&pData->lock ){ + *ppIter = pData->lock.pNext; + break; + } } - sqlite3_free(pLock); - sqlite3HashInsert(&async.aLock, pData->zName, pData->nName, 0); - if( !sqliteHashFirst(&async.aLock) ){ - sqlite3HashClear(&async.aLock); + if( !pLock->pList ){ + AsyncLock **pp; + if( pLock->pFile ){ + pLock->pFile->pMethods->xClose(pLock->pFile); + } + for(pp=&async.pLock; *pp!=pLock; pp=&((*pp)->pNext)); + *pp = pLock->pNext; + sqlite3_free(pLock); + }else{ + rc = getFileLock(pLock); } - }else{ - rc = getFileLock(pLock); } return rc; @@ -1009,7 +1050,7 @@ static int asyncOpen( sqlite3_vfs *pVfs = (sqlite3_vfs *)pAsyncVfs->pAppData; AsyncFile *p = (AsyncFile *)pFile; - int nName = strlen(zName)+1; + int nName = 0; int rc = SQLITE_OK; int nByte; AsyncFileData *pData; @@ -1017,6 +1058,11 @@ static int asyncOpen( char *z; int isExclusive = (flags&SQLITE_OPEN_EXCLUSIVE); + /* If zName is NULL, then the upper layer is requesting an anonymous file */ + if( zName ){ + nName = strlen(zName)+1; + } + nByte = ( sizeof(AsyncFileData) + /* AsyncFileData structure */ 2 * pVfs->szOsFile + /* AsyncFileData.pBaseRead and pBaseWrite */ @@ -1032,44 +1078,48 @@ static int asyncOpen( pData->pBaseRead = (sqlite3_file*)z; z += pVfs->szOsFile; pData->pBaseWrite = (sqlite3_file*)z; - z += pVfs->szOsFile; - pData->zName = z; - pData->nName = nName; pData->close.pFileData = pData; pData->close.op = ASYNC_CLOSE; - memcpy(pData->zName, zName, nName); + + if( zName ){ + z += pVfs->szOsFile; + pData->zName = z; + pData->nName = nName; + memcpy(pData->zName, zName, nName); + } if( !isExclusive ){ - rc = sqlite3OsOpen(pVfs, zName, pData->pBaseRead, flags, pOutFlags); + rc = pVfs->xOpen(pVfs, zName, pData->pBaseRead, flags, pOutFlags); if( rc==SQLITE_OK && ((*pOutFlags)&SQLITE_OPEN_READWRITE) ){ - rc = sqlite3OsOpen(pVfs, zName, pData->pBaseWrite, flags, 0); + rc = pVfs->xOpen(pVfs, zName, pData->pBaseWrite, flags, 0); } } pthread_mutex_lock(&async.lockMutex); - if( rc==SQLITE_OK ){ - pLock = sqlite3HashFind(&async.aLock, pData->zName, pData->nName); + if( zName && rc==SQLITE_OK ){ + pLock = findLock(pData->zName, pData->nName); if( !pLock ){ - pLock = sqlite3MallocZero(pVfs->szOsFile + sizeof(AsyncLock)); + int nByte = pVfs->szOsFile + sizeof(AsyncLock) + pData->nName + 1; + pLock = (AsyncLock *)sqlite3_malloc(nByte); if( pLock ){ - AsyncLock *pDelete; + memset(pLock, 0, nByte); #ifdef ENABLE_FILE_LOCKING if( flags&SQLITE_OPEN_MAIN_DB ){ pLock->pFile = (sqlite3_file *)&pLock[1]; - rc = sqlite3OsOpen(pVfs, zName, pLock->pFile, flags, 0); + rc = pVfs->xOpen(pVfs, zName, pLock->pFile, flags, 0); if( rc!=SQLITE_OK ){ sqlite3_free(pLock); pLock = 0; } } #endif - pDelete = sqlite3HashInsert( - &async.aLock, pData->zName, pData->nName, (void *)pLock - ); - if( pDelete ){ - rc = SQLITE_NOMEM; - sqlite3_free(pLock); + if( pLock ){ + pLock->nFile = pData->nName; + pLock->zFile = &((char *)(&pLock[1]))[pVfs->szOsFile]; + memcpy(pLock->zFile, pData->zName, pLock->nFile); + pLock->pNext = async.pLock; + async.pLock = pLock; } }else{ rc = SQLITE_NOMEM; @@ -1078,21 +1128,24 @@ static int asyncOpen( } if( rc==SQLITE_OK ){ - HashElem *pElem; p->pMethod = &async_methods; p->pData = pData; /* Link AsyncFileData.lock into the linked list of ** AsyncFileLock structures for this file. */ - pData->lock.pNext = pLock->pList; - pLock->pList = &pData->lock; - - pElem = sqlite3HashFindElem(&async.aLock, pData->zName, pData->nName); - pData->zName = (char *)sqliteHashKey(pElem); + if( zName ){ + pData->lock.pNext = pLock->pList; + pLock->pList = &pData->lock; + pData->zName = pLock->zFile; + } }else{ - sqlite3OsClose(pData->pBaseRead); - sqlite3OsClose(pData->pBaseWrite); + if( pData->pBaseRead->pMethods ){ + pData->pBaseRead->pMethods->xClose(pData->pBaseRead); + } + if( pData->pBaseWrite->pMethods ){ + pData->pBaseWrite->pMethods->xClose(pData->pBaseWrite); + } sqlite3_free(pData); } @@ -1100,10 +1153,11 @@ static int asyncOpen( if( rc==SQLITE_OK ){ incrOpenFileCount(); + pData->pLock = pLock; } if( rc==SQLITE_OK && isExclusive ){ - rc = addNewAsyncWrite(pData, ASYNC_OPENEXCLUSIVE, (i64)flags, 0, 0); + rc = addNewAsyncWrite(pData, ASYNC_OPENEXCLUSIVE, (sqlite3_int64)flags,0,0); if( rc==SQLITE_OK ){ if( pOutFlags ) *pOutFlags = flags; }else{ @@ -1145,12 +1199,13 @@ static int asyncAccess( ); pthread_mutex_lock(&async.queueMutex); - rc = sqlite3OsAccess(pVfs, zName, flags, &ret); + rc = pVfs->xAccess(pVfs, zName, flags, &ret); if( rc==SQLITE_OK && flags==SQLITE_ACCESS_EXISTS ){ for(p=async.pQueueFirst; p; p = p->pNext){ if( p->op==ASYNC_DELETE && 0==strcmp(p->zBuf, zName) ){ ret = 0; }else if( p->op==ASYNC_OPENEXCLUSIVE + && p->pFileData->zName && 0==strcmp(p->pFileData->zName, zName) ){ ret = 1; @@ -1178,7 +1233,7 @@ static int asyncFullPathname( ){ int rc; sqlite3_vfs *pVfs = (sqlite3_vfs *)pAsyncVfs->pAppData; - rc = sqlite3OsFullPathname(pVfs, zPath, nPathOut, zPathOut); + rc = pVfs->xFullPathname(pVfs, zPath, nPathOut, zPathOut); /* Because of the way intra-process file locking works, this backend ** needs to return a canonical path. The following block assumes the @@ -1286,14 +1341,9 @@ static sqlite3_vfs async_vfs = { static void asyncEnable(int enable){ if( enable ){ if( !async_vfs.pAppData ){ - static int hashTableInit = 0; async_vfs.pAppData = (void *)sqlite3_vfs_find(0); async_vfs.mxPathname = ((sqlite3_vfs *)async_vfs.pAppData)->mxPathname; sqlite3_vfs_register(&async_vfs, 1); - if( !hashTableInit ){ - sqlite3HashInit(&async.aLock, SQLITE_HASH_BINARY, 1); - hashTableInit = 1; - } } }else{ if( async_vfs.pAppData ){ @@ -1398,27 +1448,31 @@ static void *asyncWriterThread(void *pIsStarted){ assert( pBase ); ASYNC_TRACE(("WRITE %s %d bytes at %d\n", p->pFileData->zName, p->nByte, p->iOffset)); - rc = sqlite3OsWrite(pBase, (void *)(p->zBuf), p->nByte, p->iOffset); + rc = pBase->pMethods->xWrite(pBase, (void *)(p->zBuf), p->nByte, p->iOffset); break; case ASYNC_SYNC: assert( pBase ); ASYNC_TRACE(("SYNC %s\n", p->pFileData->zName)); - rc = sqlite3OsSync(pBase, p->nByte); + rc = pBase->pMethods->xSync(pBase, p->nByte); break; case ASYNC_TRUNCATE: assert( pBase ); ASYNC_TRACE(("TRUNCATE %s to %d bytes\n", p->pFileData->zName, p->iOffset)); - rc = sqlite3OsTruncate(pBase, p->iOffset); + rc = pBase->pMethods->xTruncate(pBase, p->iOffset); break; case ASYNC_CLOSE: { AsyncFileData *pData = p->pFileData; ASYNC_TRACE(("CLOSE %s\n", p->pFileData->zName)); - sqlite3OsClose(pData->pBaseWrite); - sqlite3OsClose(pData->pBaseRead); + if( pData->pBaseWrite->pMethods ){ + pData->pBaseWrite->pMethods->xClose(pData->pBaseWrite); + } + if( pData->pBaseRead->pMethods ){ + pData->pBaseRead->pMethods->xClose(pData->pBaseRead); + } /* Unlink AsyncFileData.lock from the linked list of AsyncFileLock ** structures for this file. Obtain the async.lockMutex mutex @@ -1435,7 +1489,6 @@ static void *asyncWriterThread(void *pIsStarted){ } case ASYNC_UNLOCK: { - AsyncLock *pLock; AsyncFileData *pData = p->pFileData; int eLock = p->nByte; pthread_mutex_lock(&async.lockMutex); @@ -1443,15 +1496,14 @@ static void *asyncWriterThread(void *pIsStarted){ pData->lock.eAsyncLock, MAX(pData->lock.eLock, eLock) ); assert(pData->lock.eAsyncLock>=pData->lock.eLock); - pLock = sqlite3HashFind(&async.aLock, pData->zName, pData->nName); - rc = getFileLock(pLock); + rc = getFileLock(pData->pLock); pthread_mutex_unlock(&async.lockMutex); break; } case ASYNC_DELETE: ASYNC_TRACE(("DELETE %s\n", p->zBuf)); - rc = sqlite3OsDelete(pVfs, p->zBuf, (int)p->iOffset); + rc = pVfs->xDelete(pVfs, p->zBuf, (int)p->iOffset); break; case ASYNC_OPENEXCLUSIVE: { @@ -1459,7 +1511,7 @@ static void *asyncWriterThread(void *pIsStarted){ AsyncFileData *pData = p->pFileData; ASYNC_TRACE(("OPEN %s flags=%d\n", p->zBuf, (int)p->iOffset)); assert(pData->pBaseRead->pMethods==0 && pData->pBaseWrite->pMethods==0); - rc = sqlite3OsOpen(pVfs, pData->zName, pData->pBaseRead, flags, 0); + rc = pVfs->xOpen(pVfs, pData->zName, pData->pBaseRead, flags, 0); assert( holdingMutex==0 ); pthread_mutex_lock(&async.queueMutex); holdingMutex = 1; @@ -1511,7 +1563,7 @@ static void *asyncWriterThread(void *pIsStarted){ if( async.ioError && !async.pQueueFirst ){ pthread_mutex_lock(&async.lockMutex); - if( 0==sqliteHashFirst(&async.aLock) ){ + if( 0==async.pLock ){ async.ioError = SQLITE_OK; } pthread_mutex_unlock(&async.lockMutex); @@ -1524,7 +1576,7 @@ static void *asyncWriterThread(void *pIsStarted){ pthread_mutex_unlock(&async.queueMutex); holdingMutex = 0; if( async.ioDelay>0 ){ - sqlite3OsSleep(pVfs, async.ioDelay); + pVfs->xSleep(pVfs, async.ioDelay); }else{ sched_yield(); } -- 2.47.3