bug in libpgtcl listen

From: Massimo Dal Zotto <dz(at)cs(dot)unitn(dot)it>
To: hackers(at)postgreSQL(dot)org (PostgreSQL Hackers)
Subject: bug in libpgtcl listen
Date: 1999-01-08 15:41:48
Message-ID: 199901081541.QAA04318@nikita.wizard.net
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hi,

I found a bug in the notify handler of the libpgtcl interface.
If I have setup a notify handler and the backend dies, the tcl interpreter
will not remove the handler and loop forever with a bad fd in select().
I tested the bug with Tcl7.5 and the following code:

$ wish
% set tcl_version
7.5
% set tk_version
4.1
% source pg_test.tcl
% connect dz
pgsql4
% sql select 123
123
% listen
% notify
% --> callback test

# From another shell kill the backend:
$ kill 3937

# Now the wish shell is looping forever in the following syscall:
$ strace -p 3934
select(5, [0 3 4], [], [], NULL) = -1 EBADF (Bad file number)
select(5, [0 3 4], [], [], NULL) = -1 EBADF (Bad file number)
select(5, [0 3 4], [], [], NULL) = -1 EBADF (Bad file number)
select(5, [0 3 4], [], [], NULL) = -1 EBADF (Bad file number)
select(5, [0 3 4], [], [], NULL) = -1 EBADF (Bad file number)
...

# The fd 4 doesn't exists anymore because it has been closed by pqReadData.
$ ls -l /proc/3934/fd
total 0
lrwx------ 1 dz users 64 Jan 8 16:00 0 -> [0801]:2081
lrwx------ 1 dz users 64 Jan 8 16:00 1 -> [0801]:2081
lrwx------ 1 dz users 64 Jan 8 16:00 2 -> [0801]:2081
lrwx------ 1 dz users 64 Jan 8 16:00 3 -> [0000]:12617

This is the test file loaded in the above example:

# pg_test.tcl --
#
# Test libpgtcl interface

load libpgtcl.so.2

proc connect {{db dz}} {
global conn
set conn [pg_connect $db]
}

proc sql {args} {
global conn
if {$args != {}} {
set cmd $args
} else {
set cmd "select 1"
}
set res [pg_exec $conn $cmd]
switch [pg_result $res -status] {
PGRES_TUPLES_OK {
for {set n 0} {$n < [pg_result $res -numTuples]} {incr n} {
puts [pg_result $res -getTuple $n]
}
}
PGRES_COMMAND_OK {
}
default {
puts [pg_result $res -status]
}
}
pg_result $res -clear
}

proc disconnect {} {
global conn
pg_disconnect $conn
set conn {}
}

proc listen {{relname test}} {
global conn
pg_listen $conn $relname "callback $relname"
}

proc unlisten {{relname test}} {
global conn
pg_listen $conn $relname {}
}

proc notify {{relname test}} {
global conn
sql notify $relname
}

proc callback {args} {
puts "--> callback $args"
}

# end of file

The following patch seems to fix the problem:

*** src/interfaces/libpgtcl/pgtclId.c.orig Mon Sep 21 03:02:03 1998
--- src/interfaces/libpgtcl/pgtclId.c Fri Jan 8 16:27:51 1999
***************
*** 638,649 ****
Pg_Notify_FileHandler (ClientData clientData, int mask)
{
Pg_ConnectionId *connid = (Pg_ConnectionId *) clientData;

/*
* Consume any data available from the SQL server (this just buffers
* it internally to libpq; but it will clear the read-ready condition).
*/
! PQconsumeInput(connid->conn);

/* Transfer notify events from libpq to Tcl event queue. */
PgNotifyTransferEvents(connid);
--- 638,656 ----
Pg_Notify_FileHandler (ClientData clientData, int mask)
{
Pg_ConnectionId *connid = (Pg_ConnectionId *) clientData;
+ int status;

/*
* Consume any data available from the SQL server (this just buffers
* it internally to libpq; but it will clear the read-ready condition).
+ *
+ * Must check the connection status and stop the event source for
+ * closed connection. -- dz
*/
! status = PQconsumeInput(connid->conn);
! if (status == 0) {
! PgStopNotifyEventSource(connid);
! }

/* Transfer notify events from libpq to Tcl event queue. */
PgNotifyTransferEvents(connid);

--
Massimo Dal Zotto

+----------------------------------------------------------------------+
| Massimo Dal Zotto email: dz(at)cs(dot)unitn(dot)it |
| Via Marconi, 141 phone: ++39-0461534251 |
| 38057 Pergine Valsugana (TN) www: http://www.cs.unitn.it/~dz/ |
| Italy pgp: finger dz(at)tango(dot)cs(dot)unitn(dot)it |
+----------------------------------------------------------------------+

Browse pgsql-hackers by date

  From Date Subject
Next Message Massimo Dal Zotto 1999-01-08 15:53:55 postgres and year 2000
Previous Message Kevin Heflin 1999-01-08 14:52:38 Re: [GENERAL] select using date