Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit00482fd

Browse files
committed
Partial solution for 'unexpected EOF' problem with pg_disconnect: it
seems we have a choice between annoying messages and leaking memory(or dumping core, but that's right out). Patch also fixes severalother problems in pg_disconnect, such as being willing to close achannel that isn't a PG channel.
1 parentb28b053 commit00482fd

File tree

2 files changed

+36
-13
lines changed

2 files changed

+36
-13
lines changed

‎src/interfaces/libpgtcl/pgtclCmds.c

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/interfaces/libpgtcl/Attic/pgtclCmds.c,v 1.66 2002/09/0221:51:47 tgl Exp $
11+
* $Header: /cvsroot/pgsql/src/interfaces/libpgtcl/Attic/pgtclCmds.c,v 1.67 2002/09/0223:41:16 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -399,7 +399,6 @@ Pg_connect(ClientData cData, Tcl_Interp *interp, int argc, char *argv[])
399399
int
400400
Pg_disconnect(ClientDatacData,Tcl_Interp*interp,intargc,char*argv[])
401401
{
402-
Pg_ConnectionId*connid;
403402
PGconn*conn;
404403
Tcl_Channelconn_chan;
405404

@@ -413,15 +412,14 @@ Pg_disconnect(ClientData cData, Tcl_Interp *interp, int argc, char *argv[])
413412
if (conn_chan==NULL)
414413
{
415414
Tcl_ResetResult(interp);
416-
Tcl_AppendResult(interp,argv[1]," is not a valid connection\n",0);
415+
Tcl_AppendResult(interp,argv[1]," is not a valid connection",0);
417416
returnTCL_ERROR;
418417
}
419418

420-
#ifTCL_MAJOR_VERSION >=8
421-
conn=PgGetConnectionId(interp,argv[1],&connid);
422-
if (connid->notifier_channel!=NULL)
423-
Tcl_UnregisterChannel(interp,connid->notifier_channel);
424-
#endif
419+
/* Check that it is a PG connection and not something else */
420+
conn=PgGetConnectionId(interp,argv[1], (Pg_ConnectionId**)NULL);
421+
if (conn== (PGconn*)NULL)
422+
returnTCL_ERROR;
425423

426424
returnTcl_UnregisterChannel(interp,conn_chan);
427425
}

‎src/interfaces/libpgtcl/pgtclId.c

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
* Portions Copyright (c) 1994, Regents of the University of California
1414
*
1515
* IDENTIFICATION
16-
* $Header: /cvsroot/pgsql/src/interfaces/libpgtcl/Attic/pgtclId.c,v 1.33 2002/09/0221:51:47 tgl Exp $
16+
* $Header: /cvsroot/pgsql/src/interfaces/libpgtcl/Attic/pgtclId.c,v 1.34 2002/09/0223:41:17 tgl Exp $
1717
*
1818
*-------------------------------------------------------------------------
1919
*/
@@ -144,6 +144,7 @@ static void
144144
PgWatchProc(ClientDatainstanceData,intmask)
145145
{
146146
}
147+
147148
staticint
148149
PgGetHandleProc(ClientDatainstanceData,intdirection,
149150
ClientData*handlePtr)
@@ -193,7 +194,7 @@ PgSetConnectionId(Tcl_Interp *interp, PGconn *conn)
193194

194195
#ifTCL_MAJOR_VERSION >=8
195196
connid->notifier_channel=Tcl_MakeTcpClientChannel((ClientData)PQsocket(conn));
196-
Tcl_RegisterChannel(interp,connid->notifier_channel);
197+
Tcl_RegisterChannel(NULL,connid->notifier_channel);
197198
#else
198199
connid->notifier_socket=-1;
199200
#endif
@@ -227,6 +228,8 @@ PgGetConnectionId(Tcl_Interp *interp, char *id, Pg_ConnectionId ** connid_p)
227228
{
228229
Tcl_ResetResult(interp);
229230
Tcl_AppendResult(interp,id," is not a valid postgresql connection",0);
231+
if (connid_p)
232+
*connid_p=NULL;
230233
return (PGconn*)NULL;
231234
}
232235

@@ -285,6 +288,25 @@ PgDelConnectionId(DRIVER_DEL_PROTO)
285288
PQfinish(connid->conn);
286289
connid->conn=NULL;
287290

291+
/*
292+
* Kill the notifier channel, too. We must not do this until after
293+
* we've closed the libpq connection, because Tcl will try to close
294+
* the socket itself!
295+
*
296+
* XXX Unfortunately, while this works fine if we are closing due to
297+
* explicit pg_disconnect, Tcl versions through 8.3.3 dump core if we
298+
* try to do it during interpreter shutdown. Not clear why, or if
299+
* there is a workaround. For now, accept leakage of the (fairly
300+
* small) amount of memory taken for the channel state representation.
301+
* Note we are not leaking a socket, since libpq closed that already.
302+
*/
303+
#ifdefNOT_USED
304+
#ifTCL_MAJOR_VERSION >=8
305+
if (connid->notifier_channel!=NULL)
306+
Tcl_UnregisterChannel(NULL,connid->notifier_channel);
307+
#endif
308+
#endif
309+
288310
/*
289311
* We must use Tcl_EventuallyFree because we don't want the connid
290312
* struct to vanish instantly if Pg_Notify_EventProc is active for it.
@@ -782,8 +804,10 @@ PgStartNotifyEventSource(Pg_ConnectionId * connid)
782804
if (pqsock >=0)
783805
{
784806
#ifTCL_MAJOR_VERSION >=8
785-
Tcl_CreateChannelHandler(connid->notifier_channel,TCL_READABLE,
786-
Pg_Notify_FileHandler, (ClientData)connid);
807+
Tcl_CreateChannelHandler(connid->notifier_channel,
808+
TCL_READABLE,
809+
Pg_Notify_FileHandler,
810+
(ClientData)connid);
787811
#else
788812
/* In Tcl 7.5 and 7.6, we need to gin up a Tcl_File. */
789813
Tcl_Filetclfile=Tcl_GetFile((ClientData)pqsock,TCL_UNIX_FD);
@@ -805,7 +829,8 @@ PgStopNotifyEventSource(Pg_ConnectionId * connid, bool allevents)
805829
{
806830
#ifTCL_MAJOR_VERSION >=8
807831
Tcl_DeleteChannelHandler(connid->notifier_channel,
808-
Pg_Notify_FileHandler, (ClientData)connid);
832+
Pg_Notify_FileHandler,
833+
(ClientData)connid);
809834
#else
810835
/* In Tcl 7.5 and 7.6, we need to gin up a Tcl_File. */
811836
Tcl_Filetclfile=Tcl_GetFile((ClientData)connid->notifier_socket,

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp