Re: libpgtcl: pq_recvbuf: unexpected EOF on client connection - Mailing list pgsql-interfaces

From Tom Lane
Subject Re: libpgtcl: pq_recvbuf: unexpected EOF on client connection
Date
Msg-id 28530.1031010328@sss.pgh.pa.us
Whole thread Raw
In response to Re: libpgtcl: pq_recvbuf: unexpected EOF on client connection  (Gerhard Hintermayer <g.hintermayer@inode.at>)
List pgsql-interfaces
Gerhard Hintermayer <g.hintermayer@inode.at> writes:
> I don't understand what you're thinking of, because the unregistering
> triggers the call to PgDelConnectionId, so who will close the
> connection if you remove the unregister call ?

I meant the unregister of the notifier_channel, which is not
Pg_disconnect's business anyway.  Unfortunately, it seems this fixes
your problem but creates a bigger one: Tcl dumps core if you shut down
the interpreter without having done pg_disconnect.

As a compromise I've applied the attached patch, which seems to suppress
the "unexpected EOF" problem at the cost of leaking a small amount of
memory for each disconnect.
        regards, tom lane

*** src/interfaces/libpgtcl/pgtclCmds.c.orig    Mon Sep  2 17:51:47 2002
--- src/interfaces/libpgtcl/pgtclCmds.c    Mon Sep  2 18:03:35 2002
***************
*** 399,405 **** int Pg_disconnect(ClientData cData, Tcl_Interp *interp, int argc, char *argv[]) {
-     Pg_ConnectionId *connid;     PGconn       *conn;     Tcl_Channel conn_chan; 
--- 399,404 ----
***************
*** 413,427 ****     if (conn_chan == NULL)     {         Tcl_ResetResult(interp);
!         Tcl_AppendResult(interp, argv[1], " is not a valid connection\n", 0);         return TCL_ERROR;     } 
! #if TCL_MAJOR_VERSION >= 8
!     conn = PgGetConnectionId(interp, argv[1], &connid);
!     if (connid->notifier_channel != NULL)
!         Tcl_UnregisterChannel(interp, connid->notifier_channel);
! #endif      return Tcl_UnregisterChannel(interp, conn_chan); }
--- 412,425 ----     if (conn_chan == NULL)     {         Tcl_ResetResult(interp);
!         Tcl_AppendResult(interp, argv[1], " is not a valid connection", 0);         return TCL_ERROR;     } 
!     /* Check that it is a PG connection and not something else */
!     conn = PgGetConnectionId(interp, argv[1], (Pg_ConnectionId **) NULL);
!     if (conn == (PGconn *) NULL)
!         return TCL_ERROR;      return Tcl_UnregisterChannel(interp, conn_chan); }
*** src/interfaces/libpgtcl/pgtclId.c.orig    Mon Sep  2 17:51:47 2002
--- src/interfaces/libpgtcl/pgtclId.c    Mon Sep  2 19:38:22 2002
***************
*** 193,199 ****  #if TCL_MAJOR_VERSION >= 8     connid->notifier_channel = Tcl_MakeTcpClientChannel((ClientData)
PQsocket(conn));
!     Tcl_RegisterChannel(interp, connid->notifier_channel); #else     connid->notifier_socket = -1; #endif
--- 194,200 ----  #if TCL_MAJOR_VERSION >= 8     connid->notifier_channel = Tcl_MakeTcpClientChannel((ClientData)
PQsocket(conn));
!     Tcl_RegisterChannel(NULL, connid->notifier_channel); #else     connid->notifier_socket = -1; #endif
***************
*** 286,291 ****
--- 289,313 ----     connid->conn = NULL;      /*
+      * Kill the notifier channel, too.  We must not do this until after
+      * we've closed the libpq connection, because Tcl will try to close
+      * the socket itself!
+      *
+      * XXX Unfortunately, while this works fine if we are closing due to
+      * explicit pg_disconnect, Tcl versions through 8.3.3 dump core if we
+      * try to do it during interpreter shutdown.  Not clear why, or if
+      * there is a workaround.  For now, accept leakage of the (fairly
+      * small) amount of memory taken for the channel state representation.
+      * Note we are not leaking a socket, since libpq closed that already.
+      */
+ #ifdef NOT_USED
+ #if TCL_MAJOR_VERSION >= 8
+     if (connid->notifier_channel != NULL)
+         Tcl_UnregisterChannel(NULL, connid->notifier_channel);
+ #endif
+ #endif
+ 
+     /*      * We must use Tcl_EventuallyFree because we don't want the connid      * struct to vanish instantly if
Pg_Notify_EventProcis active for it.      * (Otherwise, closing the connection from inside a pg_listen callback
 


pgsql-interfaces by date:

Previous
From: Gerhard Hintermayer
Date:
Subject: Re: libpgtcl: pq_recvbuf: unexpected EOF on client connection
Next
From: Bruce Momjian
Date:
Subject: Re: libpgtcl modifications