Adjust rename on Win32 to only link to temp name while holding lock,
authorBruce Momjian <bruce@momjian.us>
Mon, 2 Feb 2004 00:17:23 +0000 (00:17 +0000)
committerBruce Momjian <bruce@momjian.us>
Mon, 2 Feb 2004 00:17:23 +0000 (00:17 +0000)
then release locks and loop over renaming to active file name.

src/backend/commands/user.c
src/backend/utils/cache/relcache.c
src/backend/utils/misc/guc.c
src/include/port.h
src/port/dirmod.c

index 6a9ba6f529a78194d5bfa351d27c837a306297f0..33eb3c39b2fac26038c1faa7f0a1deab55c4b3ce 100644 (file)
@@ -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
        }
 
        /*
index fa8e2ac4d7b3ea34e29aa8282cb9075de123da3e..37b81f1244f8021ffb3671ca234a7dc2ca45584d 100644 (file)
@@ -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);
 }
 
 /*
index 9e7264c9b32626d64263b1e854b17fcca7e6ed44..ebc17830d3c3e00ac427e4b5560f671aeb94f50a 100644 (file)
@@ -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);
index cfc82b83680810addcac9f8d18aec78517c7b2e7..67e16e1aae4332e1ceff2dd92b964de841f0f9d7 100644 (file)
@@ -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 */
index 15e1290f6d32d35bfa39a6688c39e30fa1854165..45a99216c35b83662e1f32d40c190ce449cb459c 100644 (file)
@@ -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 */