Non-blocking socket still blocking!
Eric Norum
eric at cls.usask.ca
Fri Sep 1 21:25:47 UTC 2000
"Smith, Gene" wrote:
>
> I noticed that my read() on a supposedly non-blocking socket still blocked
> after
> I had read all data from the socket and called read() again. I then checked
>
> the socket flags more closely to make sure I was really setting it
> non-blocking
> (O_NONBLOCK is 0x4000) with the following code:
>
> /* set new_sock non-blocking */
> flags = 0;
> flags = fcntl( new_sock, F_GETFL, 0);
> DTRACE(("\nOrig flags = 0x%x", flags));
> flags = flags | O_NONBLOCK;
> DTRACE(("\nflags|O_NON_BLOCK=0x%x", flags));
> if ( fcntl( new_sock, F_SETFL, flags ) < 0)
> RTEMS_PANIC(("\nCan't set new_sock non-blocking"));
> DTRACE(("\nflags set to 0x%x", flags));
>
> /* verify non-blocking flag set */
> flags = 0;
> flags = fcntl( new_sock, F_GETFL, 0);
> if ( (flags & O_NONBLOCK) == 0 )
> DTRACE(("\nBad flags = 0x%x", flags));
> else
> DTRACE(("\nGood flags = 0x%x", flags));
>
> The following output trace indicates that my attempt to set the socket
> non-blocking does not "stick." (The value "new_sock" is the return value
> from
> accept().) Any ideas why the socket seems to remain blocking?
>
> Orig flags = 0x2
> flags|O_NON_BLOCK=0x4002
> flags set to 0x4002
> Bad flags = 0x2
>
This looks like the kind of problem that pops up when merging code from
widely different systems. The socket-specific fcntl
handler(rtems_bsdnet_fcntl) is being passed a pointer to an
rtems_libio_t but is using the flags in this structure as fcntl flags.
Unfortunately the flags have been mangled from fcntl to libio by
rtems_libio_fcntl_flags().
Here's a patch for the socket-specific code. Unfortunately it seems
that the code in libio.c which is converting the fcntl flags to and from
the libio flags still seems to be clearing the non-blocking
(O_NDELAY/O_NONBLOCK) bit somehow. I don't have time to look into
this. Joel??
diff -ur
rtems-ss-20000811.orig/c/src/libnetworking/rtems/rtems_syscall.c
rtems-ss-20000811/c/src/libnetworking/rtems/rtems_syscall.c
--- rtems-ss-20000811.orig/c/src/libnetworking/rtems/rtems_syscall.c
Mon Jun 12 09:00:08 2000
+++ rtems-ss-20000811/c/src/libnetworking/rtems/rtems_syscall.c Fri Sep
1 14:54:16 2000
@@ -730,7 +730,7 @@
rtems_bsdnet_semaphore_release ();
return EBADF;
}
- if (iop->flags & O_NONBLOCK)
+ if (iop->flags & LIBIO_FLAGS_NO_DELAY)
so->so_state |= SS_NBIO;
else
so->so_state &= ~SS_NBIO;
Amazing how long a bug like this can lurk. I guess everyone else has
been using ioctl (FIONBIO) to set the non-blocking state!
--
Eric Norum eric at cls.usask.ca
Canadian Light Source Phone: (306) 966-6308
University of Saskatchewan FAX: (306) 966-6058
Saskatoon, Canada.
More information about the users
mailing list