Flush pending errors in gr_udp_sink on disconnect()
authorDon Ward <don2387ward@sprynet.com>
Thu, 6 May 2010 14:02:35 +0000 (10:02 -0400)
committerDon Ward <don2387ward@sprynet.com>
Thu, 6 May 2010 18:40:48 +0000 (14:40 -0400)
On some systems (e.g., Debian/lenny) UDP errors are reported on the
following send() or recv() call.  To avoid having errors (such as
ECONNREFUSED) from an old connection showing up on the first write
to a new connection, we do a recv() on disconnect() to flush them.
This may not work for all errors on all systems, but it works in
some simple cases of interest.

gnuradio-core/src/lib/io/gr_udp_sink.cc

index a9cb87a21e323db842371b423650a8c28847093c..a323aef986d940b9b5b3a591497a48077faa91a6 100755 (executable)
@@ -251,6 +251,31 @@ void gr_udp_sink::disconnect()
       (void) send( d_socket, NULL, 0, 0 );  // ignore errors
   }
 
+  // Sending EOF can produce ERRCONNREFUSED errors that won't show up
+  //  until the next send or recv, which might confuse us if it happens
+  //  on a new connection.  The following does a nonblocking recv to
+  //  clear any such errors.
+  timeval timeout;
+  timeout.tv_sec = 0;    // zero time for immediate return
+  timeout.tv_usec = 0;
+  fd_set readfds;
+  FD_ZERO(&readfds);
+  FD_SET(d_socket, &readfds);
+  int r = select(FD_SETSIZE, &readfds, NULL, NULL, &timeout);
+  if(r < 0) {
+      #if SNK_VERBOSE
+      report_error("udp_sink/select",NULL);
+      #endif
+  }
+  else if(r > 0) {  // call recv() to get error return
+    r = recv(d_socket, (char*)&readfds, sizeof(readfds), 0);
+    if(r < 0) {
+       #if SNK_VERBOSE
+       report_error("udp_sink/recv",NULL);
+       #endif
+    }
+  }
+
   // Since I can't find any way to disconnect a datagram socket in Cygwin,
   // we just leave it connected but disable sending.
 #if 0