summaryrefslogtreecommitdiff
path: root/src/port/dirmod.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/port/dirmod.c')
-rw-r--r--src/port/dirmod.c46
1 files changed, 31 insertions, 15 deletions
diff --git a/src/port/dirmod.c b/src/port/dirmod.c
index 724ef0620f8..d317cb446fd 100644
--- a/src/port/dirmod.c
+++ b/src/port/dirmod.c
@@ -10,7 +10,7 @@
* Win32 (NT, Win2k, XP). replace() doesn't work on Win95/98/Me.
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/port/dirmod.c,v 1.44.2.3 2008/04/12 00:00:08 tgl Exp $
+ * $PostgreSQL: pgsql/src/port/dirmod.c,v 1.44.2.4 2009/09/13 18:32:35 heikki Exp $
*
*-------------------------------------------------------------------------
*/
@@ -117,10 +117,11 @@ pgrename(const char *from, const char *to)
int loops = 0;
/*
- * We need to loop because even though PostgreSQL uses flags that
- * allow rename while the file is open, other applications might have
- * the file open without those flags. However, we won't wait
- * indefinitely for someone else to close the file.
+ * We need to loop because even though PostgreSQL uses flags that allow
+ * rename while the file is open, other applications might have the file
+ * open without those flags. However, we won't wait indefinitely for
+ * someone else to close the file, as the caller might be holding locks
+ * and blocking other backends.
*/
#if defined(WIN32) && !defined(__CYGWIN__)
while (!MoveFileEx(from, to, MOVEFILE_REPLACE_EXISTING))
@@ -129,13 +130,28 @@ pgrename(const char *from, const char *to)
#endif
{
#if defined(WIN32) && !defined(__CYGWIN__)
- if (GetLastError() != ERROR_ACCESS_DENIED)
+ DWORD err = GetLastError();
+
+ _dosmaperr(err);
+
+ /*
+ * Modern NT-based Windows versions return ERROR_SHARING_VIOLATION
+ * if another process has the file open without FILE_SHARE_DELETE.
+ * ERROR_LOCK_VIOLATION has also been seen with some anti-virus
+ * software. This used to check for just ERROR_ACCESS_DENIED, so
+ * presumably you can get that too with some OS versions. We don't
+ * expect real permission errors where we currently use rename().
+ */
+ if (err != ERROR_ACCESS_DENIED &&
+ err != ERROR_SHARING_VIOLATION &&
+ err != ERROR_LOCK_VIOLATION)
+ return -1;
#else
if (errno != EACCES)
-#endif
- /* set errno? */
return -1;
- if (++loops > 300) /* time out after 30 sec */
+#endif
+
+ if (++loops > 100) /* time out after 10 sec */
return -1;
pg_usleep(100000); /* us */
}
@@ -152,17 +168,17 @@ pgunlink(const char *path)
int loops = 0;
/*
- * We need to loop because even though PostgreSQL uses flags that
- * allow unlink while the file is open, other applications might have
- * the file open without those flags. However, we won't wait
- * indefinitely for someone else to close the file.
+ * We need to loop because even though PostgreSQL uses flags that allow
+ * unlink while the file is open, other applications might have the file
+ * open without those flags. However, we won't wait indefinitely for
+ * someone else to close the file, as the caller might be holding locks
+ * and blocking other backends.
*/
while (unlink(path))
{
if (errno != EACCES)
- /* set errno? */
return -1;
- if (++loops > 300) /* time out after 30 sec */
+ if (++loops > 100) /* time out after 10 sec */
return -1;
pg_usleep(100000); /* us */
}