aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2005-12-01 20:24:49 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2005-12-01 20:24:49 +0000
commiteeae797d33ab9c45f70b52c3e19d7ac271b59f77 (patch)
treeda33368f1e695056be7e95d53808246629b2bf34
parent64c09adea7d221ab2e1f0389cf94f3925bc8618f (diff)
downloadpostgresql-eeae797d33ab9c45f70b52c3e19d7ac271b59f77.tar.gz
postgresql-eeae797d33ab9c45f70b52c3e19d7ac271b59f77.zip
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.
-rw-r--r--src/backend/storage/file/fd.c61
1 files changed, 58 insertions, 3 deletions
diff --git a/src/backend/storage/file/fd.c b/src/backend/storage/file/fd.c
index a7540c1fc44..e7dd00e62cc 100644
--- a/src/backend/storage/file/fd.c
+++ b/src/backend/storage/file/fd.c
@@ -7,7 +7,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/storage/file/fd.c,v 1.115.4.1 2005/08/07 18:47:38 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/storage/file/fd.c,v 1.115.4.2 2005/12/01 20:24:49 tgl Exp $
*
* NOTES:
*
@@ -983,11 +983,41 @@ FileRead(File file, char *buffer, int amount)
if (returnCode < 0)
return returnCode;
+retry:
returnCode = read(VfdCache[file].fd, buffer, amount);
- if (returnCode > 0)
+
+ if (returnCode >= 0)
VfdCache[file].seekPos += returnCode;
else
+ {
+ /*
+ * Windows may run out of kernel buffers and return "Insufficient
+ * system resources" error. Wait a bit and retry to solve it.
+ *
+ * It is rumored that EINTR is also possible on some Unix filesystems,
+ * in which case immediate retry is indicated.
+ */
+#ifdef WIN32
+ DWORD error = GetLastError();
+
+ switch (error)
+ {
+ case ERROR_NO_SYSTEM_RESOURCES:
+ pg_usleep(1000L);
+ errno = EINTR;
+ break;
+ default:
+ _dosmaperr(error);
+ break;
+ }
+#endif
+ /* OK to retry if interrupted */
+ if (errno == EINTR)
+ goto retry;
+
+ /* Trouble, so assume we don't know the file position anymore */
VfdCache[file].seekPos = FileUnknownPos;
+ }
return returnCode;
}
@@ -1007,6 +1037,7 @@ FileWrite(File file, char *buffer, int amount)
if (returnCode < 0)
return returnCode;
+retry:
errno = 0;
returnCode = write(VfdCache[file].fd, buffer, amount);
@@ -1014,10 +1045,34 @@ FileWrite(File file, char *buffer, int amount)
if (returnCode != amount && errno == 0)
errno = ENOSPC;
- if (returnCode > 0)
+ if (returnCode >= 0)
VfdCache[file].seekPos += returnCode;
else
+ {
+ /*
+ * See comments in FileRead()
+ */
+#ifdef WIN32
+ DWORD error = GetLastError();
+
+ switch (error)
+ {
+ case ERROR_NO_SYSTEM_RESOURCES:
+ pg_usleep(1000L);
+ errno = EINTR;
+ break;
+ default:
+ _dosmaperr(error);
+ break;
+ }
+#endif
+ /* OK to retry if interrupted */
+ if (errno == EINTR)
+ goto retry;
+
+ /* Trouble, so assume we don't know the file position anymore */
VfdCache[file].seekPos = FileUnknownPos;
+ }
return returnCode;
}