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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy