Fix libpq memory leak during PQreset() --- closePGconn() was not
authorTom Lane
Wed, 13 Jul 2005 15:25:55 +0000 (15:25 +0000)
committerTom Lane
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;