diff options
Diffstat (limited to 'src/port/dirmod.c')
-rw-r--r-- | src/port/dirmod.c | 46 |
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 */ } |