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