]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
I/O errors shut down all processing on the same file in test_async.c. (CVS 3087)
authordrh <drh@noemail.net>
Mon, 13 Feb 2006 13:50:55 +0000 (13:50 +0000)
committerdrh <drh@noemail.net>
Mon, 13 Feb 2006 13:50:55 +0000 (13:50 +0000)
FossilOrigin-Name: 4366e7121703a18ebb799dfa4f168b3b2508604e

manifest
manifest.uuid
src/test_async.c

index 3035aea54a1785f99996261c8257d6bb17121418..f2782e4d6df9864328719e1f20ba100a32630db1 100644 (file)
--- 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
index bc2eb19f7d469a96a21e0ce30ff99ab7786c8bb3..992e65a824d518268fefb3d9b1511a3fcb91cefe 100644 (file)
@@ -1 +1 @@
-ad25127b067b3135694ddb0de552aad981640669
\ No newline at end of file
+4366e7121703a18ebb799dfa4f168b3b2508604e
\ No newline at end of file
index 8a55b5609e4ada73992ac83fe3654945bc99730e..e88a43d523746434e25fe67790980efdb15e021b 100644 (file)
@@ -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 );