From: drh Date: Wed, 23 Feb 2011 14:33:31 +0000 (+0000) Subject: Automatically retry system calls that fail with EINTR. This is a backport X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=refs%2Fheads%2Fbranch-3.7.4;p=thirdparty%2Fsqlite.git Automatically retry system calls that fail with EINTR. This is a backport of the changes from [b9d29ea385bafc] and [af9ba2a6d2c379]. FossilOrigin-Name: 8609a15dfad23a7c5311b52617d5c4818c0b8d1e --- diff --git a/manifest b/manifest index f7bcb79803..92661a3637 100644 --- a/manifest +++ b/manifest @@ -1,8 +1,8 @@ -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 -C Backport\sthe\sos_unix.c\serror\slogging\senhancements\sfrom\ncheck-in\s[01076528a43b61a]. -D 2011-02-23T14:05:08.407 +C Automatically\sretry\ssystem\scalls\sthat\sfail\swith\sEINTR.\s\sThis\sis\sa\sbackport\nof\sthe\schanges\sfrom\s[b9d29ea385bafc]\sand\s[af9ba2a6d2c379]. +D 2011-02-23T14:33:31.368 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f F Makefile.in 4547616ad2286053af6ccccefa242dc925e49bf0 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23 @@ -163,7 +163,7 @@ F src/os.c 22ac61d06e72a0dac900400147333b07b13d8e1d F src/os.h 9dbed8c2b9c1f2f2ebabc09e49829d4777c26bf9 F src/os_common.h a8f95b81eca8a1ab8593d23e94f8a35f35d4078f F src/os_os2.c 72d0b2e562952a2464308c4ce5f7913ac10bef3e -F src/os_unix.c c9f2a09124d78e2accd5738c78aabbccc07cb2f4 +F src/os_unix.c ef71b9892af48871a448c7f4ca662ecd287e70dd F src/os_win.c 2f90f7bdec714fad51cd31b4ecad3cc1b4bb5aad F src/pager.c 5b2210b4307c626a3b3ed7312161ec533958c094 F src/pager.h 0ea59db2a33bc6c2c02cae34de33367e1effdf76 @@ -898,14 +898,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f -P 692aafb17e7fca4e303ca14da2925cb95a22f71e -R 6770e6a4b417ada2ff6c98dd3dca2daa +P a4333b1545c6f96caef5b6dfaf94c8446e1b5d44 +R 110fc06a15d59c992fa93576aaf0f07d U drh -Z 9c3c0b89eea505163f9778dd289c331f +Z 728d442c3a16d050cc4bf0099d5aa1fd -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) -iD8DBQFNZRQXoxKgR168RlERAqTcAJ4i0CBz9MzbV5ibLtQ/BGYBaqlYuwCfXQoY -oux3l0HUdLba9EsW1zRLA/k= -=uIBr +iD8DBQFNZRq+oxKgR168RlERAjAUAJ4icN9NAHBEFsKwW+tePI8D7yuS5QCeJfkr +4CvelEbFUjjp0LZiOQzb+aA= +=6ZlI -----END PGP SIGNATURE----- diff --git a/manifest.uuid b/manifest.uuid index 989b74e812..b41bd21df7 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -a4333b1545c6f96caef5b6dfaf94c8446e1b5d44 \ No newline at end of file +8609a15dfad23a7c5311b52617d5c4818c0b8d1e \ No newline at end of file diff --git a/src/os_unix.c b/src/os_unix.c index 102a2bffa6..4b389af869 100644 --- a/src/os_unix.c +++ b/src/os_unix.c @@ -394,6 +394,19 @@ static int lockTrace(int fd, int op, struct flock *p){ #endif /* SQLITE_LOCK_TRACE */ +/* +** Retry ftruncate() calls that fail due to EINTR +*/ +#ifdef EINTR +static int robust_ftruncate(int h, sqlite3_int64 sz){ + int rc; + do{ rc = ftruncate(h,sz); }while( rc<0 && errno==EINTR ); + return rc; +} +#else +# define robust_ftruncate(a,b) ftruncate(a,b) +#endif + /* ** This routine translates a standard POSIX errno code into something @@ -912,7 +925,7 @@ static int findInodeInfo( ** the first page of the database, no damage is done. */ if( statbuf.st_size==0 && (pFile->fsFlags & SQLITE_FSFLAGS_IS_MSDOS)!=0 ){ - rc = write(fd, "S", 1); + do{ rc = write(fd, "S", 1); }while( rc<0 && errno==EINTR ); if( rc!=1 ){ pFile->lastErrno = errno; return SQLITE_IOERR; @@ -1788,6 +1801,20 @@ static int dotlockClose(sqlite3_file *id) { */ #if SQLITE_ENABLE_LOCKING_STYLE && !OS_VXWORKS +/* +** Retry flock() calls that fail with EINTR +*/ +#ifdef EINTR +static int robust_flock(int fd, int op){ + int rc; + do{ rc = flock(fd,op); }while( rc<0 && errno==EINTR ); + return rc; +} +#else +# define robust_flock(a,b) flock(a,b) +#endif + + /* ** This routine checks if there is a RESERVED lock held on the specified ** file by this or any other process. If such a lock is held, set *pResOut @@ -1811,10 +1838,10 @@ static int flockCheckReservedLock(sqlite3_file *id, int *pResOut){ /* Otherwise see if some other process holds it. */ if( !reserved ){ /* attempt to get the lock */ - int lrc = flock(pFile->h, LOCK_EX | LOCK_NB); + int lrc = robust_flock(pFile->h, LOCK_EX | LOCK_NB); if( !lrc ){ /* got the lock, unlock it */ - lrc = flock(pFile->h, LOCK_UN); + lrc = robust_flock(pFile->h, LOCK_UN); if ( lrc ) { int tErrno = errno; /* unlock failed with an error */ @@ -1891,7 +1918,7 @@ static int flockLock(sqlite3_file *id, int eFileLock) { /* grab an exclusive lock */ - if (flock(pFile->h, LOCK_EX | LOCK_NB)) { + if (robust_flock(pFile->h, LOCK_EX | LOCK_NB)) { int tErrno = errno; /* didn't get, must be busy */ rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); @@ -1940,7 +1967,7 @@ static int flockUnlock(sqlite3_file *id, int eFileLock) { } /* no, really, unlock. */ - int rc = flock(pFile->h, LOCK_UN); + int rc = robust_flock(pFile->h, LOCK_UN); if (rc) { int r, tErrno = errno; r = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK); @@ -2677,10 +2704,10 @@ static int seekAndRead(unixFile *id, sqlite3_int64 offset, void *pBuf, int cnt){ #endif TIMER_START; #if defined(USE_PREAD) - got = pread(id->h, pBuf, cnt, offset); + do{ got = pread(id->h, pBuf, cnt, offset); }while( got<0 && errno==EINTR ); SimulateIOError( got = -1 ); #elif defined(USE_PREAD64) - got = pread64(id->h, pBuf, cnt, offset); + do{ got = pread64(id->h, pBuf, cnt, offset); }while( got<0 && errno==EINTR ); SimulateIOError( got = -1 ); #else newOffset = lseek(id->h, offset, SEEK_SET); @@ -2693,7 +2720,7 @@ static int seekAndRead(unixFile *id, sqlite3_int64 offset, void *pBuf, int cnt){ } return -1; } - got = read(id->h, pBuf, cnt); + do{ got = read(id->h, pBuf, cnt); }while( got<0 && errno==EINTR ); #endif TIMER_END; if( got<0 ){ @@ -2755,9 +2782,9 @@ static int seekAndWrite(unixFile *id, i64 offset, const void *pBuf, int cnt){ #endif TIMER_START; #if defined(USE_PREAD) - got = pwrite(id->h, pBuf, cnt, offset); + do{ got = pwrite(id->h, pBuf, cnt, offset); }while( got<0 && errno==EINTR ); #elif defined(USE_PREAD64) - got = pwrite64(id->h, pBuf, cnt, offset); + do{ got = pwrite64(id->h, pBuf, cnt, offset); }while( got<0 && errno==EINTR ); #else newOffset = lseek(id->h, offset, SEEK_SET); if( newOffset!=offset ){ @@ -2768,7 +2795,7 @@ static int seekAndWrite(unixFile *id, i64 offset, const void *pBuf, int cnt){ } return -1; } - got = write(id->h, pBuf, cnt); + do{ got = write(id->h, pBuf, cnt); }while( got<0 && errno==EINTR ); #endif TIMER_END; if( got<0 ){ @@ -3059,7 +3086,7 @@ static int unixTruncate(sqlite3_file *id, i64 nByte){ nByte = ((nByte + pFile->szChunk - 1)/pFile->szChunk) * pFile->szChunk; } - rc = ftruncate(pFile->h, (off_t)nByte); + rc = robust_ftruncate(pFile->h, (off_t)nByte); if( rc ){ pFile->lastErrno = errno; return unixLogError(SQLITE_IOERR_TRUNCATE, "ftruncate", pFile->zPath); @@ -3134,9 +3161,11 @@ static int fcntlSizeHint(unixFile *pFile, i64 nByte){ nSize = ((nByte+pFile->szChunk-1) / pFile->szChunk) * pFile->szChunk; if( nSize>(i64)buf.st_size ){ #if defined(HAVE_POSIX_FALLOCATE) && HAVE_POSIX_FALLOCATE - if( posix_fallocate(pFile->h, buf.st_size, nSize-buf.st_size) ){ - return SQLITE_IOERR_WRITE; - } + int rc; + do{ + rc = posix_fallocate(pFile-.h, buf.st_size, nSize-buf.st_size; + }while( rc<0 && errno=EINTR ); + if( rc ) return SQLITE_IOERR_WRITE; #else /* If the OS does not have posix_fallocate(), fake it. First use ** ftruncate() to set the file size, then write a single byte to @@ -3148,7 +3177,7 @@ static int fcntlSizeHint(unixFile *pFile, i64 nByte){ i64 iWrite; /* Next offset to write to */ int nWrite; /* Return value from seekAndWrite() */ - if( ftruncate(pFile->h, nSize) ){ + if( robust_ftruncate(pFile->h, nSize) ){ pFile->lastErrno = errno; return unixLogError(SQLITE_IOERR_TRUNCATE, "ftruncate", pFile->zPath); } @@ -3505,7 +3534,7 @@ static int unixOpenSharedMemory(unixFile *pDbFd){ */ rc = SQLITE_OK; if( unixShmSystemLock(pShmNode, F_WRLCK, UNIX_SHM_DMS, 1)==SQLITE_OK ){ - if( ftruncate(pShmNode->h, 0) ){ + if( robust_ftruncate(pShmNode->h, 0) ){ rc = unixLogError(SQLITE_IOERR_SHMOPEN, "ftruncate", zShmFilename); } } @@ -3611,7 +3640,7 @@ static int unixShmMap( ** the requested memory region. */ if( !bExtend ) goto shmpage_out; - if( ftruncate(pShmNode->h, nByte) ){ + if( robust_ftruncate(pShmNode->h, nByte) ){ rc = unixLogError(SQLITE_IOERR_SHMSIZE,"ftruncate",pShmNode->zFilename); goto shmpage_out; } @@ -5008,7 +5037,7 @@ static int unixRandomness(sqlite3_vfs *NotUsed, int nBuf, char *zBuf){ assert( sizeof(t)+sizeof(pid)<=(size_t)nBuf ); nBuf = sizeof(t) + sizeof(pid); }else{ - nBuf = read(fd, zBuf, nBuf); + do{ nBuf = read(fd, zBuf, nBuf); }while( nBuf<0 && errno==EINTR ); close(fd); } } @@ -5768,7 +5797,7 @@ static int proxyTakeConch(unixFile *pFile){ strlcpy(&writeBuffer[PROXY_PATHINDEX], tempLockPath, MAXPATHLEN); } writeSize = PROXY_PATHINDEX + strlen(&writeBuffer[PROXY_PATHINDEX]); - ftruncate(conchFile->h, writeSize); + robust_ftruncate(conchFile->h, writeSize); rc = unixWrite((sqlite3_file *)conchFile, writeBuffer, writeSize, 0); fsync(conchFile->h); /* If we created a new conch file (not just updated the contents of a @@ -5776,6 +5805,7 @@ static int proxyTakeConch(unixFile *pFile){ */ if( rc==SQLITE_OK && createConch ){ struct stat buf; + int rc; int err = fstat(pFile->h, &buf); if( err==0 ){ mode_t cmode = buf.st_mode&(S_IRUSR|S_IWUSR | S_IRGRP|S_IWGRP | @@ -5784,7 +5814,10 @@ static int proxyTakeConch(unixFile *pFile){ #ifndef SQLITE_PROXY_DEBUG fchmod(conchFile->h, cmode); #else - if( fchmod(conchFile->h, cmode)!=0 ){ + do{ + rc = fchmod(conchFile->h, cmode); + }while( rc==(-1) && errno==EINTR ); + if( rc!=0 ){ int code = errno; fprintf(stderr, "fchmod %o FAILED with %d %s\n", cmode, code, strerror(code));