Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | I/O errors shut down all processing on the same file in test_async.c. (CVS 3087) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
4366e7121703a18ebb799dfa4f168b3b |
User & Date: | drh 2006-02-13 13:50:56.000 |
Context
2006-02-13
| ||
14:49 | Improvements to the TRACE macro in test_async.c. (CVS 3088) (check-in: 4c6dfec54f user: drh tags: trunk) | |
13:50 | I/O errors shut down all processing on the same file in test_async.c. (CVS 3087) (check-in: 4366e71217 user: drh tags: trunk) | |
13:30 | Fix overlapping read logic in the test_async.c demonstration. (CVS 3086) (check-in: ad25127b06 user: drh tags: trunk) | |
Changes
Changes to src/test_async.c.
︙ | ︙ | |||
240 241 242 243 244 245 246 247 248 249 250 251 252 253 | PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, PTHREAD_COND_INITIALIZER, }; /* Possible values of AsyncWrite.op */ #define ASYNC_WRITE 1 #define ASYNC_SYNC 2 #define ASYNC_TRUNCATE 3 #define ASYNC_CLOSE 4 #define ASYNC_OPENDIRECTORY 5 #define ASYNC_SETFULLSYNC 6 | > | 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 | PTHREAD_MUTEX_INITIALIZER, PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, PTHREAD_COND_INITIALIZER, }; /* Possible values of AsyncWrite.op */ #define ASYNC_NOOP 0 #define ASYNC_WRITE 1 #define ASYNC_SYNC 2 #define ASYNC_TRUNCATE 3 #define ASYNC_CLOSE 4 #define ASYNC_OPENDIRECTORY 5 #define ASYNC_SETFULLSYNC 6 |
︙ | ︙ | |||
310 311 312 313 314 315 316 | }; /* ** The AsyncFile structure is a subclass of OsFile used for asynchronous IO. */ struct AsyncFile { IoMethod *pMethod; /* Must be first */ | | | 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 | }; /* ** The AsyncFile structure is a subclass of OsFile used for asynchronous IO. */ struct AsyncFile { IoMethod *pMethod; /* Must be first */ 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 */ }; /* ** Add an entry to the end of the global write-op list. pWrite should point ** to an AsyncWrite structure allocated using sqlite3OsMalloc(). The writer |
︙ | ︙ | |||
359 360 361 362 363 364 365 | static int addNewAsyncWrite( AsyncFile *pFile, int op, i64 iOffset, int nByte, const char *zByte ){ | > > > > | | 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 | static int addNewAsyncWrite( AsyncFile *pFile, int op, i64 iOffset, int nByte, const char *zByte ){ AsyncWrite *p; if( pFile && pFile->ioError!=SQLITE_OK ){ return pFile->ioError; } p = sqlite3OsMalloc(sizeof(AsyncWrite) + (zByte?nByte:0)); if( !p ){ return SQLITE_NOMEM; } p->op = op; p->iOffset = iOffset; p->nByte = nByte; p->pFile = pFile; |
︙ | ︙ | |||
445 446 447 448 449 450 451 452 453 454 455 456 457 458 | ** This method holds the mutex from start to finish. */ static int asyncRead(OsFile *id, void *obuf, int amt){ int rc = SQLITE_OK; i64 filesize; int nRead; AsyncFile *pFile = (AsyncFile *)id; /* Grab the write queue mutex for the duration of the call */ pthread_mutex_lock(&async.queueMutex); if( pFile->pBaseRead ){ rc = sqlite3OsFileSize(pFile->pBaseRead, &filesize); if( rc!=SQLITE_OK ){ | > > > > > > > | 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 | ** This method holds the mutex from start to finish. */ static int asyncRead(OsFile *id, void *obuf, int amt){ int rc = SQLITE_OK; i64 filesize; 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); if( pFile->pBaseRead ){ rc = sqlite3OsFileSize(pFile->pBaseRead, &filesize); if( rc!=SQLITE_OK ){ |
︙ | ︙ | |||
642 643 644 645 646 647 648 649 650 651 652 653 654 655 | goto error_out; } memset(p, 0, sizeof(AsyncFile)); p->pMethod = &iomethod; p->pBaseRead = pBaseRead; p->pBaseWrite = pBaseWrite; *pFile = (OsFile *)p; return SQLITE_OK; error_out: assert(!p); sqlite3OsClose(&pBaseRead); | > | 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 | goto error_out; } memset(p, 0, sizeof(AsyncFile)); p->pMethod = &iomethod; p->pBaseRead = pBaseRead; p->pBaseWrite = pBaseWrite; p->ioError = SQLITE_OK; *pFile = (OsFile *)p; return SQLITE_OK; error_out: assert(!p); sqlite3OsClose(&pBaseRead); |
︙ | ︙ | |||
840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 | ** variable. ** * ASYNC_SYNC and ASYNC_WRITE operations, if ** SQLITE_ASYNC_TWO_FILEHANDLES was set at compile time and two ** file-handles are open for the particular file being "synced". */ if( p->pFile ){ pBase = p->pFile->pBaseWrite; if( p->op==ASYNC_CLOSE || p->op==ASYNC_OPENEXCLUSIVE || (pBase && (p->op==ASYNC_SYNC || p->op==ASYNC_WRITE) ) ){ pthread_mutex_unlock(&async.queueMutex); holdingMutex = 0; } if( !pBase ){ pBase = p->pFile->pBaseRead; } } switch( p->op ){ case ASYNC_WRITE: assert( pBase ); rc = sqlite3OsSeek(pBase, p->iOffset); if( rc==SQLITE_OK ){ rc = sqlite3OsWrite(pBase, (const void *)(p->zBuf), p->nByte); } break; | > > > > > > | 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 | ** variable. ** * ASYNC_SYNC and ASYNC_WRITE operations, if ** SQLITE_ASYNC_TWO_FILEHANDLES was set at compile time and two ** file-handles are open for the particular file being "synced". */ 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 || (pBase && (p->op==ASYNC_SYNC || p->op==ASYNC_WRITE) ) ){ pthread_mutex_unlock(&async.queueMutex); holdingMutex = 0; } if( !pBase ){ pBase = p->pFile->pBaseRead; } } switch( p->op ){ case ASYNC_NOOP: break; case ASYNC_WRITE: assert( pBase ); rc = sqlite3OsSeek(pBase, p->iOffset); if( rc==SQLITE_OK ){ rc = sqlite3OsWrite(pBase, (const void *)(p->zBuf), p->nByte); } break; |
︙ | ︙ | |||
912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 | pFile->pBaseRead = pBase; } break; } default: assert(!"Illegal value for AsyncWrite.op"); } /* 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. */ if( !holdingMutex ){ pthread_mutex_lock(&async.queueMutex); holdingMutex = 1; } TRACE("UNLINK %p\n", p); | > > > > > > > > > > > > > < | | | | < | 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 | pFile->pBaseRead = pBase; } break; } 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. */ if( !holdingMutex ){ pthread_mutex_lock(&async.queueMutex); holdingMutex = 1; } TRACE("UNLINK %p\n", p); if( p==async.pQueueLast ){ async.pQueueLast = 0; } async.pQueueFirst = p->pNext; sqlite3OsFree(p); assert( holdingMutex ); /* Drop the queue mutex before continuing to the next write operation ** in order to give other threads a chance to work with the write queue. */ pthread_mutex_unlock(&async.queueMutex); |
︙ | ︙ |