Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

libpgtcl: pq_recvbuf: unexpected EOF on client connection

0 views
Skip to first unread message

Gerhard Hintermayer

unread,
Sep 2, 2002, 4:45:38 AM9/2/02
to
I constantly keep getting this message in the log files when
disconnection with pg_disconnect (TCL-interface) I did an upgrade to
7.2.1 in combination with Tcl8.3.4, everything works, but that message
is annoying. Using psql doesn't produce any log entrys.
Even a simple script
set conn [pg_connect ....]
pg_disconnect $conn

creates the log entry. Has anyone ever encountered that problem ?

Gerhard

--
Gerhard Hintermayer
http://www.inode.at/g.hintermayer

Tom Lane

unread,
Sep 2, 2002, 11:54:19 AM9/2/02
to
g.hint...@inode.at (Gerhard Hintermayer) writes:
> I constantly keep getting this message in the log files when
> disconnection with pg_disconnect (TCL-interface)

Yeah, I see it too --- though everything's fine if you just exit the
client program without an explicit pg_disconnect. I think the problem
is that pg_disconnect shouldn't be unregistering the notifier_channel;
I bet TCL thinks it should close the socket when we do that. Then
the later PQfinish call will be unable to send the normal termination
message to the backend. Probably the best fix is to move the unregister
call into PgDelConnectionId(), after we do PQfinish.

regards, tom lane

---------------------------(end of broadcast)---------------------------
TIP 3: if posting/reading through Usenet, please send an appropriate
subscribe-nomail command to majo...@postgresql.org so that your
message can get through to the mailing list cleanly

Gerhard Hintermayer

unread,
Sep 2, 2002, 12:34:53 PM9/2/02
to
Tom Lane wrote:
> g.hint...@inode.at (Gerhard Hintermayer) writes:
>
>>I constantly keep getting this message in the log files when
>>disconnection with pg_disconnect (TCL-interface)
>
>
> Yeah, I see it too --- though everything's fine if you just exit the
> client program without an explicit pg_disconnect. I think the problem
> is that pg_disconnect shouldn't be unregistering the notifier_channel;
> I bet TCL thinks it should close the socket when we do that. Then
> the later PQfinish call will be unable to send the normal termination
> message to the backend. Probably the best fix is to move the unregister
> call into PgDelConnectionId(), after we do PQfinish.
>
> regards, tom lane

Hope my posting works.

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 wonder what has changed either in the Tcl or the PQ internals, since this
worked in Tcl8.3.2 combined with PostgreSQL 7.0.2. Going to check that tomorrow
at work.
Btw, is the PQfinish syncroneous (?) or not ? Maybe the problem is we're sending
the X and close the connection immediately instead of letting the server close it.

Tom Lane

unread,
Sep 2, 2002, 7:45:35 PM9/2/02
to
Gerhard Hintermayer <g.hint...@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_EventProc is active for it.
* (Otherwise, closing the connection from inside a pg_listen callback

---------------------------(end of broadcast)---------------------------
TIP 6: Have you searched our list archives?

http://archives.postgresql.org

0 new messages