ok, finally got it.
let me know if this looks ok.
you first use fcntl to set the socket to non-blocking mode.
then you connect , expecting errno to be EINPROGRESS, ...then selecting on the socket with a timeout value to see if it is ready.
Olaf, this should fix the same problem with oggamp~ and mp3amp~.....and I noticed that x_net.c from pd/src is affected by this problem
netsend will hang and block pd entirely on a netsend connect to certain ip's and ports.
this should also "fix" that as well, assuming pd is willing to wait for a timeval while connecting with netsend. the comments in .37 version suggest that this will be put into a thread.
thanks for the help -august.
----------------------------------------
int flags = fcntl( fd, F_GETFL, 0); fcntl( fd, F_SETFL, FNDELAY); // make this socket's calls non-blocking // fcntl( fd, F_SETFL, flags | O_NONBLOCK);
if (connect( fd, (struct sockaddr *) &server, sizeof(server) ) == -1 && errno != EINPROGRESS) { /* * If non-blocking connect() couldn't finish, it returns * EINPROGRESS. That's OK, we'll take care of it a little * later, in the select(). But if some other error code was * returned there's a real problem... */ sys_closesocket (fd); return(-1);
} else {
FD_ZERO (&fdset); FD_SET (fd, &fdset); tv.tv_sec = 1; /* seconds */ tv.tv_usec = 0; /* microseconds */
// you want to do the select on the WRITEablity of the socket, // HTTP expects a get command, so make sure to pass args to // both read and write fdset switch (select( fd+1 , &fdset, &fdset, NULL, &tv) ) { /* * select() will return when the socket is ready for action, * or when there is an error, or the when timeout specified * using tval is exceeded without anything becoming ready. */
case 0: // timeout //do whatever you do when you couldn't connect cout << "InputStream:: connect timed out" <<endl; sys_closesocket (fd); return (-1); break; case -1: // error cout << "InputStream:: connection error" <<endl; sys_closesocket (fd); return (-1); break; default: // your file descriptor is ready... fcntl( fd, F_SETFL, flags); break; } }