Commit d9d2ca8e authored by Bruce Momjian's avatar Bruce Momjian

Adjust rename on Win32 to only link to temp name while holding lock,

then release locks and loop over renaming to active file name.
parent e5e5a323
......@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/backend/commands/user.c,v 1.133 2004/01/26 22:35:32 tgl Exp $
* $PostgreSQL: pgsql/src/backend/commands/user.c,v 1.134 2004/02/02 00:17:21 momjian Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -139,7 +139,11 @@ write_group_file(Relation grel)
bufsize = strlen(filename) + 12;
tempname = (char *) palloc(bufsize);
snprintf(tempname, bufsize, "%s.%d", filename, MyProcPid);
#if defined(WIN32) || defined(CYGWIN)
filename = repalloc(filename, strlen(filename) + 1 + strlen(".new");
strcat(filename, ".new");
#endif
oumask = umask((mode_t) 077);
fp = AllocateFile(tempname, "w");
umask(oumask);
......@@ -286,6 +290,10 @@ write_user_file(Relation urel)
bufsize = strlen(filename) + 12;
tempname = (char *) palloc(bufsize);
snprintf(tempname, bufsize, "%s.%d", filename, MyProcPid);
#if defined(WIN32) || defined(CYGWIN)
filename = repalloc(filename, strlen(filename) + 1 + strlen(".new");
strcat(filename, ".new");
#endif
oumask = umask((mode_t) 077);
fp = AllocateFile(tempname, "w");
......@@ -457,6 +465,18 @@ AtEOXact_UpdatePasswordFile(bool isCommit)
user_file_update_needed = false;
write_user_file(urel);
heap_close(urel, NoLock);
#if defined(WIN32) || defined(CYGWIN)
{
/* Rename active file while not holding an exclusive lock */
char *filename = user_getfilename(), *filename_new;
filename_new = palloc(strlen(filename) + 1 + strlen(".new")));
sprintf(filename_new, "%s.new", filename);
rename(filename_new, filename);
pfree(filename);
pfree(filename_new);
}
#endif
}
if (group_file_update_needed)
......@@ -464,6 +484,18 @@ AtEOXact_UpdatePasswordFile(bool isCommit)
group_file_update_needed = false;
write_group_file(grel);
heap_close(grel, NoLock);
#if defined(WIN32) || defined(CYGWIN)
{
/* Rename active file while not holding an exclusive lock */
char *filename = group_getfilename(), *filename_new;
filename_new = palloc(strlen(filename) + 1 + strlen(".new")));
sprintf(filename_new, "%s.new", filename);
rename(filename_new, filename);
pfree(filename);
pfree(filename_new);
}
#endif
}
/*
......
......@@ -8,7 +8,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/cache/relcache.c,v 1.195 2004/01/26 22:35:32 tgl Exp $
* $PostgreSQL: pgsql/src/backend/utils/cache/relcache.c,v 1.196 2004/02/02 00:17:21 momjian Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -3358,33 +3358,28 @@ write_relcache_init_file(void)
/*
* OK, rename the temp file to its final name, deleting any
* previously-existing init file.
*
* Note: a failure here is possible under Cygwin, if some other
* backend is holding open an unlinked-but-not-yet-gone init file.
* So treat this as a noncritical failure.
*/
if (rename(tempfilename, finalfilename) < 0)
#if defined(WIN32) || defined(CYGWIN)
rename(tempfilename, finalfilename);
LWLockRelease(RelCacheInitLock);
#else
{
ereport(WARNING,
(errcode_for_file_access(),
errmsg("could not rename relation-cache initialization file \"%s\" to \"%s\": %m",
tempfilename, finalfilename),
errdetail("Continuing anyway, but there's something wrong.")));
/*
* If we fail, try to clean up the useless temp file; don't
* bother to complain if this fails too.
*/
unlink(tempfilename);
char finalfilename_new[MAXPGPATH];
snprintf(finalfilename_new, sizeof(finalfilename_new), "%s.new", finalfilename);
rename(tempfilename, finalfilename_new);
LWLockRelease(RelCacheInitLock);
/* Rename to active file after lock is released */
rename(finalfilename_new, finalfilename);
}
#endif
}
else
{
/* Delete the already-obsolete temp file */
unlink(tempfilename);
LWLockRelease(RelCacheInitLock);
}
LWLockRelease(RelCacheInitLock);
}
/*
......
......@@ -10,7 +10,7 @@
* Written by Peter Eisentraut <peter_e@gmx.net>.
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.182 2004/01/31 05:09:41 neilc Exp $
* $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.183 2004/02/02 00:17:21 momjian Exp $
*
*--------------------------------------------------------------------
*/
......@@ -3981,7 +3981,10 @@ write_nondefault_variables(GucContext context)
return;
}
/* Put new file in place, this could delay on Win32 */
/*
* Put new file in place. This could delay on Win32, but we don't hold
* any exclusive locks.
*/
rename(new_filename, filename);
free(new_filename);
free(filename);
......
......@@ -6,7 +6,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/include/port.h,v 1.16 2004/02/02 00:11:31 momjian Exp $
* $PostgreSQL: pgsql/src/include/port.h,v 1.17 2004/02/02 00:17:23 momjian Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -30,11 +30,10 @@ extern int fseeko(FILE *stream, off_t offset, int whence);
extern off_t ftello(FILE *stream);
#endif
#ifdef WIN32
#if !defined(FRONTEND) && (defined(WIN32) || defined(CYGWIN))
/*
* Win32 doesn't have reliable rename/unlink during concurrent access
*/
#ifndef FRONTEND
extern int pgrename(const char *from, const char *to);
extern int pgunlink(const char *path);
......@@ -42,6 +41,7 @@ extern int pgunlink(const char *path);
#define unlink(path) pgunlink(path)
#endif
#ifdef WIN32
extern int copydir(char *fromdir, char *todir);
/* Missing rand functions */
......
......@@ -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.8 2003/11/29 19:52:13 pgsql Exp $
* $PostgreSQL: pgsql/src/port/dirmod.c,v 1.9 2004/02/02 00:17:23 momjian Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -27,9 +27,19 @@ pgrename(const char *from, const char *to)
{
int loops = 0;
#ifdef WIN32
while (!MoveFileEx(from, to, MOVEFILE_REPLACE_EXISTING))
#endif
#ifdef CYGWIN
while (rename(from, to) < 0)
#endif
{
#ifdef WIN32
if (GetLastError() != ERROR_ACCESS_DENIED)
#endif
#ifdef CYGWIN
if (errno != EACCES)
#endif
/* set errno? */
return -1;
Sleep(100); /* ms */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment