diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2005-12-01 20:24:31 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2005-12-01 20:24:31 +0000 |
commit | 3ece85f8bf43e122fc4fa647e56c72a6511cca4f (patch) | |
tree | ab68e709227b3aa34abf2c18a59515ba0a438038 | |
parent | 963a811a67cac1935e6acfc814da35234669d6e5 (diff) | |
download | postgresql-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.
-rw-r--r-- | src/backend/storage/file/fd.c | 61 |
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; } |