From: drh Date: Mon, 13 Feb 2006 13:50:55 +0000 (+0000) Subject: I/O errors shut down all processing on the same file in test_async.c. (CVS 3087) X-Git-Tag: version-3.6.10~3080 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4b74b26052997d369b2e5af3ad0536b21a520ca6;p=thirdparty%2Fsqlite.git I/O errors shut down all processing on the same file in test_async.c. (CVS 3087) FossilOrigin-Name: 4366e7121703a18ebb799dfa4f168b3b2508604e --- diff --git a/manifest b/manifest index 3035aea54a..f2782e4d6d 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Fix\soverlapping\sread\slogic\sin\sthe\stest_async.c\sdemonstration.\s(CVS\s3086) -D 2006-02-13T13:30:19 +C I/O\serrors\sshut\sdown\sall\sprocessing\son\sthe\ssame\sfile\sin\stest_async.c.\s(CVS\s3087) +D 2006-02-13T13:50:56 F Makefile.in 5d8dff443383918b700e495de42ec65bc1c8865b F Makefile.linux-gcc 74ba0eadf88748a9ce3fd03d2a3ede2e6715baec F README 9c4e2d6706bdcc3efdd773ce752a8cdab4f90028 @@ -80,7 +80,7 @@ F src/test4.c ff4e9406b3d2809966d8f0e82468ac5508be9f56 F src/test5.c 7162f8526affb771c4ed256826eee7bb9eca265f F src/test6.c 60a02961ceb7b3edc25f5dc5c1ac2556622a76de F src/test7.c d28d3e62f9594923648fc6a8fb030eba36564ba1 -F src/test_async.c 818c346094f164a5f6d1051c5df4849f548a832c +F src/test_async.c 3788835109389314abd9281b42bdb3a39e626016 F src/test_md5.c 6c42bc0a3c0b54be34623ff77a0eec32b2fa96e3 F src/test_server.c 087b92a39d883e3fa113cae259d64e4c7438bc96 F src/tokenize.c 382b3bb0ca26eb9153b5d20b246ef512a114a24f @@ -352,7 +352,7 @@ F www/tclsqlite.tcl bb0d1357328a42b1993d78573e587c6dcbc964b9 F www/vdbe.tcl 87a31ace769f20d3627a64fa1fade7fed47b90d0 F www/version3.tcl a99cf5f6d8bd4d5537584a2b342f0fb9fa601d8b F www/whentouse.tcl 97e2b5cd296f7d8057e11f44427dea8a4c2db513 -P 904ffa4dfb60e00b01db17049de2f4934537f3d8 -R c15c7a4a0ef3b7c380f375710e72f985 +P ad25127b067b3135694ddb0de552aad981640669 +R c172fd59b56c5fed4fe5f809faeffff3 U drh -Z 3b25fcdac403270a231a8a67cd00fbda +Z 077affc5334060506b2ff1fb3322bebe diff --git a/manifest.uuid b/manifest.uuid index bc2eb19f7d..992e65a824 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -ad25127b067b3135694ddb0de552aad981640669 \ No newline at end of file +4366e7121703a18ebb799dfa4f168b3b2508604e \ No newline at end of file diff --git a/src/test_async.c b/src/test_async.c index 8a55b5609e..e88a43d523 100644 --- a/src/test_async.c +++ b/src/test_async.c @@ -244,6 +244,7 @@ static struct TestAsyncStaticData { }; /* Possible values of AsyncWrite.op */ +#define ASYNC_NOOP 0 #define ASYNC_WRITE 1 #define ASYNC_SYNC 2 #define ASYNC_TRUNCATE 3 @@ -314,7 +315,7 @@ struct AsyncWrite { */ struct AsyncFile { IoMethod *pMethod; /* Must be first */ - i64 iOffset; /* Current seek() offset in file */ + int ioError; /* Value of any asychronous error we have seen */ i64 iOffset; /* Current seek() offset in file */ OsFile *pBaseRead; /* Read handle to the underlying Os file */ OsFile *pBaseWrite; /* Write handle to the underlying Os file */ }; @@ -363,7 +364,11 @@ static int addNewAsyncWrite( int nByte, const char *zByte ){ - AsyncWrite *p = sqlite3OsMalloc(sizeof(AsyncWrite) + (zByte?nByte:0)); + AsyncWrite *p; + if( pFile && pFile->ioError!=SQLITE_OK ){ + return pFile->ioError; + } + p = sqlite3OsMalloc(sizeof(AsyncWrite) + (zByte?nByte:0)); if( !p ){ return SQLITE_NOMEM; } @@ -450,6 +455,13 @@ static int asyncRead(OsFile *id, void *obuf, int amt){ int nRead; AsyncFile *pFile = (AsyncFile *)id; + /* If an I/O error has previously occurred on this file, then all + ** subsequent operations fail. + */ + if( pFile->ioError!=SQLITE_OK ){ + return pFile->ioError; + } + /* Grab the write queue mutex for the duration of the call */ pthread_mutex_lock(&async.queueMutex); @@ -646,6 +658,7 @@ static int asyncOpenFile( p->pMethod = &iomethod; p->pBaseRead = pBaseRead; p->pBaseWrite = pBaseWrite; + p->ioError = SQLITE_OK; *pFile = (OsFile *)p; return SQLITE_OK; @@ -844,6 +857,9 @@ static void *asyncWriterThread(void *NotUsed){ */ if( p->pFile ){ pBase = p->pFile->pBaseWrite; + if( p->pFile->ioError!=SQLITE_OK && p->op!=ASYNC_CLOSE ){ + p->op = ASYNC_NOOP; + } if( p->op==ASYNC_CLOSE || p->op==ASYNC_OPENEXCLUSIVE || @@ -858,6 +874,9 @@ static void *asyncWriterThread(void *NotUsed){ } switch( p->op ){ + case ASYNC_NOOP: + break; + case ASYNC_WRITE: assert( pBase ); rc = sqlite3OsSeek(pBase, p->iOffset); @@ -917,6 +936,19 @@ static void *asyncWriterThread(void *NotUsed){ default: assert(!"Illegal value for AsyncWrite.op"); } + /* If an error happens, store the error code in the pFile.ioError + ** field. This will prevent any future operations on that file, + ** other than closing it. + ** + ** We cannot report the error back to the connection that requested + ** the I/O since the error happened asynchronously. The connection has + ** already moved on. There really is nobody to report the error to. + */ + if( rc!=SQLITE_OK ){ + p->pFile->ioError = rc; + rc = SQLITE_OK; + } + /* If we didn't hang on to the mutex during the IO op, obtain it now ** so that the AsyncWrite structure can be safely removed from the ** global write-op queue. @@ -926,12 +958,10 @@ static void *asyncWriterThread(void *NotUsed){ holdingMutex = 1; } TRACE("UNLINK %p\n", p); - if( rc==SQLITE_OK ){ - if( p==async.pQueueLast ){ - async.pQueueLast = 0; - } - async.pQueueFirst = p->pNext; + if( p==async.pQueueLast ){ + async.pQueueLast = 0; } + async.pQueueFirst = p->pNext; sqlite3OsFree(p); assert( holdingMutex );