Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit ace17c1

Browse files
committed
Retry in FileRead and FileWrite if Windows returns ERROR_NO_SYSTEM_RESOURCES.
Also add a retry for Unixen returning EINTR, which hasn't been reported as an issue but at least theoretically could be. Patch by Qingqing Zhou, some minor adjustments by me.
1 parent 277b2ea commit ace17c1

File tree

1 file changed

+58
-3
lines changed
  • src/backend/storage/file

1 file changed

+58
-3
lines changed

src/backend/storage/file/fd.c

Lines changed: 58 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1994, Regents of the University of California
88
*
99
* IDENTIFICATION
10-
* $PostgreSQL: pgsql/src/backend/storage/file/fd.c,v 1.122 2005/11/22 18:17:20 momjian Exp $
10+
* $PostgreSQL: pgsql/src/backend/storage/file/fd.c,v 1.123 2005/12/01 20:24:18 tgl Exp $
1111
*
1212
* NOTES:
1313
*
@@ -1009,11 +1009,41 @@ FileRead(File file, char *buffer, int amount)
10091009
if (returnCode < 0)
10101010
return returnCode;
10111011

1012+
retry:
10121013
returnCode = read(VfdCache[file].fd, buffer, amount);
1013-
if (returnCode > 0)
1014+
1015+
if (returnCode >= 0)
10141016
VfdCache[file].seekPos += returnCode;
10151017
else
1018+
{
1019+
/*
1020+
* Windows may run out of kernel buffers and return "Insufficient
1021+
* system resources" error. Wait a bit and retry to solve it.
1022+
*
1023+
* It is rumored that EINTR is also possible on some Unix filesystems,
1024+
* in which case immediate retry is indicated.
1025+
*/
1026+
#ifdef WIN32
1027+
DWORD error = GetLastError();
1028+
1029+
switch (error)
1030+
{
1031+
case ERROR_NO_SYSTEM_RESOURCES:
1032+
pg_usleep(1000L);
1033+
errno = EINTR;
1034+
break;
1035+
default:
1036+
_dosmaperr(error);
1037+
break;
1038+
}
1039+
#endif
1040+
/* OK to retry if interrupted */
1041+
if (errno == EINTR)
1042+
goto retry;
1043+
1044+
/* Trouble, so assume we don't know the file position anymore */
10161045
VfdCache[file].seekPos = FileUnknownPos;
1046+
}
10171047

10181048
return returnCode;
10191049
}
@@ -1033,17 +1063,42 @@ FileWrite(File file, char *buffer, int amount)
10331063
if (returnCode < 0)
10341064
return returnCode;
10351065

1066+
retry:
10361067
errno = 0;
10371068
returnCode = write(VfdCache[file].fd, buffer, amount);
10381069

10391070
/* if write didn't set errno, assume problem is no disk space */
10401071
if (returnCode != amount && errno == 0)
10411072
errno = ENOSPC;
10421073

1043-
if (returnCode > 0)
1074+
if (returnCode >= 0)
10441075
VfdCache[file].seekPos += returnCode;
10451076
else
1077+
{
1078+
/*
1079+
* See comments in FileRead()
1080+
*/
1081+
#ifdef WIN32
1082+
DWORD error = GetLastError();
1083+
1084+
switch (error)
1085+
{
1086+
case ERROR_NO_SYSTEM_RESOURCES:
1087+
pg_usleep(1000L);
1088+
errno = EINTR;
1089+
break;
1090+
default:
1091+
_dosmaperr(error);
1092+
break;
1093+
}
1094+
#endif
1095+
/* OK to retry if interrupted */
1096+
if (errno == EINTR)
1097+
goto retry;
1098+
1099+
/* Trouble, so assume we don't know the file position anymore */
10461100
VfdCache[file].seekPos = FileUnknownPos;
1101+
}
10471102

10481103
return returnCode;
10491104
}

0 commit comments

Comments
 (0)