Retry selected system calls on unix when they fail with EINTR.

FossilOrigin-Name: b9d29ea385bafcf87c7dd07822ce9ec3d3892bd1
This commit is contained in:
drh 2011-02-23 13:33:46 +00:00
parent 5b6c545ba1
commit ff81231e62
3 changed files with 64 additions and 31 deletions

View File

@ -1,8 +1,8 @@
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
C When\sa\sstale\sschema-cookie\sis\sseen,\sexpire\sonly\sthe\sone\sstatement\sthat\nencountered\sthe\sbad\scookie,\snot\severy\sstatement\son\sthe\sdatabase\s\nconnection.\s\sTicket\s[b72787b1a7cea1f]
D 2011-02-22T03:34:56.684
C Retry\sselected\ssystem\scalls\son\sunix\swhen\sthey\sfail\swith\sEINTR.
D 2011-02-23T13:33:46.402
F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
F Makefile.in 27701a1653595a1f2187dc61c8117e00a6c1d50f
F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@ -164,7 +164,7 @@ F src/os.c 22ac61d06e72a0dac900400147333b07b13d8e1d
F src/os.h 9dbed8c2b9c1f2f2ebabc09e49829d4777c26bf9
F src/os_common.h a8f95b81eca8a1ab8593d23e94f8a35f35d4078f
F src/os_os2.c 2e452c9f2ca507623ad351c33a8a8b27849b1863
F src/os_unix.c 0969a5921f2ff2a54c53d9b76eba9e4190ae9001
F src/os_unix.c 866aa2d83fa6b03972abf4e721a1e08cdbecceac
F src/os_win.c 9abdcdd925416d854eabb0996c96debd92abfef5
F src/pager.c d62dfc1d77168c4415e7f3e23c6dbee4f3fdff60
F src/pager.h 3f8c783de1d4706b40b1ac15b64f5f896bcc78d1
@ -912,14 +912,14 @@ F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
P 9f9f32882501ac9b6e60f81195a64bdbf6e4497b
R 5f31f20137e37610967a0c8c09aa1cdf
P 1bca0a7e198391202fd2bc1650c0a62028a9aaa5
R 63cd7efdc2a9ee9a3a8f0df12af55205
U drh
Z efa7e00c780185dfb46b103f7c160f16
Z 6f6b7b9fb863cbdbaba6174b19832589
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
iD8DBQFNYy7koxKgR168RlERAptAAJ0SwgTWX7lSr3APOJLkJfc852ZtVgCfcyeE
jtbsyJxLadCeUXNXPwdyqQ0=
=vXCW
iD8DBQFNZQy+oxKgR168RlERAtY5AKCNEQ7Cxp5ZJoBf1tnIV6tozsuDegCbBxJl
KHpzjHN31kdIp0EO3b2jfgs=
=cbOt
-----END PGP SIGNATURE-----

View File

@ -1 +1 @@
1bca0a7e198391202fd2bc1650c0a62028a9aaa5
b9d29ea385bafcf87c7dd07822ce9ec3d3892bd1

View File

@ -396,6 +396,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
@ -914,7 +927,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;
@ -1790,6 +1803,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) fclose(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
@ -1813,10 +1840,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 */
@ -1893,7 +1920,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);
@ -1942,7 +1969,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);
@ -2679,10 +2706,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);
@ -2695,7 +2722,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 ){
@ -2757,9 +2784,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 ){
@ -2770,7 +2797,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 ){
@ -3061,7 +3088,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);
@ -3136,9 +3163,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
@ -3150,7 +3179,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);
}
@ -3510,7 +3539,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);
}
}
@ -3616,7 +3645,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;
}
@ -5013,7 +5042,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);
}
}
@ -5774,7 +5803,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
@ -5782,6 +5811,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 |
@ -5790,7 +5820,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));