Fix libpq memory leak during PQreset() --- closePGconn() was not
authorTom Lane <tgl@sss.pgh.pa.us>
Wed, 13 Jul 2005 15:25:55 +0000 (15:25 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Wed, 13 Jul 2005 15:25:55 +0000 (15:25 +0000)
freeing all transient state of the PGconn object.

src/interfaces/libpq/fe-connect.c

index 1ededb23e20ff988fde81c44a20b05d06114cb51..4da59226b787b2b9296ef2b89f0ad7b7c00e50ac 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/interfaces/libpq/fe-connect.c,v 1.313 2005/06/27 02:04:26 neilc Exp $
+ *       $PostgreSQL: pgsql/src/interfaces/libpq/fe-connect.c,v 1.314 2005/07/13 15:25:55 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1874,6 +1874,8 @@ makeEmptyPGconn(void)
 /*
  * freePGconn
  *      - free the PGconn data structure
+ *
+ * When changing/adding to this function, see also closePGconn!
  */
 static void
 freePGconn(PGconn *conn)
@@ -1921,6 +1923,7 @@ freePGconn(PGconn *conn)
                free(conn->krbsrvname);
 #endif
        /* Note that conn->Pfdebug is not ours to close or free */
+       freeaddrinfo_all(conn->addrlist_family, conn->addrlist);
        notify = conn->notifyHead;
        while (notify != NULL)
        {
@@ -1929,7 +1932,6 @@ freePGconn(PGconn *conn)
                notify = notify->next;
                free(prev);
        }
-       freeaddrinfo_all(conn->addrlist_family, conn->addrlist);
        pstatus = conn->pstatus;
        while (pstatus != NULL)
        {
@@ -1952,10 +1954,15 @@ freePGconn(PGconn *conn)
 /*
  * closePGconn
  *      - properly close a connection to the backend
+ *
+ * Release all transient state, but NOT the connection parameters.
  */
 static void
 closePGconn(PGconn *conn)
 {
+       PGnotify   *notify;
+       pgParameterStatus *pstatus;
+
        /*
         * Note that the protocol doesn't allow us to send Terminate messages
         * during the startup phase.
@@ -1991,6 +1998,27 @@ closePGconn(PGconn *conn)
                                                                                 * absent */
        conn->asyncStatus = PGASYNC_IDLE;
        pqClearAsyncResult(conn);       /* deallocate result and curTuple */
+       freeaddrinfo_all(conn->addrlist_family, conn->addrlist);
+       conn->addrlist = NULL;
+       conn->addr_cur = NULL;
+       notify = conn->notifyHead;
+       while (notify != NULL)
+       {
+               PGnotify *prev = notify;
+
+               notify = notify->next;
+               free(prev);
+       }
+       conn->notifyHead = NULL;
+       pstatus = conn->pstatus;
+       while (pstatus != NULL)
+       {
+               pgParameterStatus *prev = pstatus;
+
+               pstatus = pstatus->next;
+               free(prev);
+       }
+       conn->pstatus = NULL;
        if (conn->lobjfuncs)
                free(conn->lobjfuncs);
        conn->lobjfuncs = NULL;