aboutsummaryrefslogtreecommitdiff
path: root/src/backend
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2005-12-01 20:24:31 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2005-12-01 20:24:31 +0000
commit3ece85f8bf43e122fc4fa647e56c72a6511cca4f (patch)
treeab68e709227b3aa34abf2c18a59515ba0a438038 /src/backend
parent963a811a67cac1935e6acfc814da35234669d6e5 (diff)
downloadpostgresql-3ece85f8bf43e122fc4fa647e56c72a6511cca4f.tar.gz
postgresql-3ece85f8bf43e122fc4fa647e56c72a6511cca4f.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.
Diffstat (limited to 'src/backend')
-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 f706e062ffd..195563ebe3c 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.121.2.1 2005/11/22 18:23:18 momjian Exp $
+ * $PostgreSQL: pgsql/src/backend/storage/file/fd.c,v 1.121.2.2 2005/12/01 20:24:31 tgl Exp $
*
* NOTES:
*
@@ -1009,11 +1009,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;
}
@@ -1033,6 +1063,7 @@ FileWrite(File file, char *buffer, int amount)
if (returnCode < 0)
return returnCode;
+retry:
errno = 0;
returnCode = write(VfdCache[file].fd, buffer, amount);
@@ -1040,10 +1071,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;
}