]> granicus.if.org Git - postgresql/commitdiff
Attached is a patch that fixes these leaks, and does a couple other
authorBruce Momjian <bruce@momjian.us>
Tue, 9 Jun 1998 04:06:12 +0000 (04:06 +0000)
committerBruce Momjian <bruce@momjian.us>
Tue, 9 Jun 1998 04:06:12 +0000 (04:06 +0000)
things as well:
  * Computes and saves a cancel key for each backend.  * fflush
  before forking, to eliminate double-buffering problems
    between postmaster and backends.

Other cleanups.

Tom Lane

src/backend/postmaster/postmaster.c

index 06ecedd21ebe032f0c558b99e6071fefb8cf0536..b657a2a64a6c05adde6567ffdc2518ea7845c5f8 100644 (file)
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.84 1998/06/08 22:28:26 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/postmaster/postmaster.c,v 1.85 1998/06/09 04:06:12 momjian Exp $
  *
  * NOTES
  *
 typedef struct bkend
 {
        int                     pid;                    /* process id of backend */
+       long            cancel_key;             /* cancel key for cancels for this backend */
 } Backend;
 
 /* list of active backends.  For garbage collection only now. */
@@ -198,7 +199,14 @@ static     sigset_t        oldsigmask,
 static int                     orgsigmask = sigblock(0);
 #endif
 
+/*
+ * State for assigning random salts and cancel keys.
+ * Also, the global MyCancelKey passes the cancel key assigned to a given
+ * backend from the postmaster to that backend (via fork).
+ */
+
 static unsigned int random_seed = 0;
+long MyCancelKey = 0;
 
 extern char *optarg;
 extern int     optind,
@@ -612,17 +620,22 @@ ServerLoop(void)
                        return (STATUS_ERROR);
                }
 
-               if (random_seed == 0)
+               /*
+                * Select a random seed at the time of first receiving a request.
+                */
+               while (random_seed == 0)
                {
                        gettimeofday(&later, &tz);
        
                        /*
                         *      We are not sure how much precision is in tv_usec, so we
-                        *      swap the nibbles of 'later' and XOR them with 'now'
+                        *      swap the nibbles of 'later' and XOR them with 'now'.
+                        *  On the off chance that the result is 0, we loop until
+                        *  it isn't.
                         */
                        random_seed = now.tv_usec ^
                                        ((later.tv_usec << 16) |
-                                       ((unsigned int)(later.tv_usec & 0xffff0000) >> 16));
+                                       ((later.tv_usec >> 16) & 0xffff));
                }
                                
                /*
@@ -1085,6 +1098,14 @@ BackendStartup(Port *port)
        }
 #endif
 
+       /*
+        * Compute the cancel key that will be assigned to this backend.
+        * The backend will have its own copy in the forked-off process'
+        * value of MyCancelKey, so that it can transmit the key to the
+        * frontend.
+        */
+       MyCancelKey = PostmasterRandom();
+
        if (DebugLvl > 2)
        {
                char      **p;
@@ -1098,17 +1119,21 @@ BackendStartup(Port *port)
                fprintf(stderr, "-----------------------------------------\n");
        }
 
+       /* Flush all stdio channels just before fork,
+        * to avoid double-output problems.
+        */
+       fflush(NULL);
+
     if ((pid = fork()) == 0)
        {  /* child */
         if (DoBackend(port))
                {
             fprintf(stderr, "%s child[%d]: BackendStartup: backend startup failed\n",
-                    progname, pid);
-                       /* use _exit to keep from double-flushing stdio */
-                       _exit(1);
+                    progname, (int) getpid());
+                       exit(1);
                }
                else
-               _exit(0);
+               exit(0);
        }
 
        /* in parent */
@@ -1140,6 +1165,7 @@ BackendStartup(Port *port)
        }
 
        bn->pid = pid;
+       bn->cancel_key = MyCancelKey;
        DLAddHead(BackendList, DLNewElem(bn));
 
        ActiveBackends = TRUE;