Hi all,
In our recent troubleshooting trying to hunt down a mysterious crash at
patch closing we uncovered a bug that appears to be present in
pd-extended 0.41.4 and 0.42.5, as well as pd vanilla (svn checked out
yesterday). Following is reproducible on Linux 9.04 Ubuntu i386.
To reproduce the crash if you run the patch included below (pretty much
vanilla version of netsend/netreceive) as follows:
#N canvas 511 186 450 322 10;
#X floatatom 80 -44 0 0 0 0 - - -;
#X floatatom 71 32 0 0 0 0 - - -;
#X obj 125 -117 tgl 15 0 empty empty empty 17 7 0 10 -262144 -1 -1
0 1;
#X obj 74 -177 loadbang;
#X obj 71 5 netsend 1;
#X floatatom 212 -18 5 0 0 0 - - -;
#X obj 214 -44 netreceive 3000 1;
#X msg 80 -17 send \$1;
#X msg 71 -157 connect 192.168.1.8 3000;
#X obj 122 -95 metro 2;
#X obj 151 -53 +;
#X msg 114 -69 1;
#X connect 0 0 7 0;
#X connect 0 0 10 1;
#X connect 2 0 9 0;
#X connect 3 0 8 0;
#X connect 4 0 1 0;
#X connect 6 0 5 0;
#X connect 7 0 4 0;
#X connect 8 0 4 0;
#X connect 9 0 11 0;
#X connect 10 0 0 0;
#X connect 11 0 10 0;
1) save the patch and click on "connect" message
2) start the metro
3) close the patch *without* stopping the metro
4) reopen it again, and you'll find pd reporting that the old connection
still exists (explained below)
5) at this point you can start the metro again (it should work)
6) however, when closing the patch pd will crash
Part of the problem:
x->x_fd in netsend_disconnect is the same flag used in netsend_send
function, so when one tries to close socket but there is still a stream
of data coming in, because x->x_fd is reverted to -1 after the attempt
to close the socket, the data keeps coming in through netsend_send
function potentially (and I speculate here) preventing socket from
closing. This leaves a stale open socket and eventually causes the whole
thing to crash.
Below is the problematic code.
static void netsend_disconnect(t_netsend *x)
{
if (x->x_fd >= 0)
{
sys_closesocket(x->x_fd);
x->x_fd = -1;
outlet_float(x->x_obj.ob_outlet, 0);
}
}
Solution is changing the netsend_disconnect to create a temp value from
the x->x_fd, change x->x_fd to -1 to prevent other incoming data from
being processed, and only then try to close the socket.
This has apparently fixed part of the problem on our end here.
Please see x_net.c patch below:
--- x_net.c.old 2009-11-18 17:45:24.000000000 -0500
+++ x_net.c 2009-11-18 17:41:38.000000000 -0500
@@ -106,8 +106,9 @@
{
if (x->x_fd >= 0)
{
- sys_closesocket(x->x_fd);
- x->x_fd = -1;
+ int tmp = x->x_fd;
+ x->x_fd = -1;
+ sys_closesocket(tmp);
outlet_float(x->x_obj.ob_outlet, 0);
}
}
The problem is this fixes crashing in a non-rt version of Pd. The rt
version however still suffers sporadically from the same problem. It may
take several tries to instigate it, but when it finally occurs, in my
case the reopening of the patch at first misbehaves in that whatever I
do on canvas with a mouse or keyboard, everything is being reported
twice (e.g. clicking on the toggle creates an on and an off event,
creating a new object creates two, typing into it creates 2 letters per
each keypress, etc.). After that closing the patch crashes pd. I've had
this occur before as well but now at least the other bug with open
socket is not there any more.
Any ideas as to why?
Ico