* [ECOS] FreeBSD problem with UDP sockets @ 2004-08-12 3:10 David Brennan 2004-08-12 8:23 ` Andrew Lunn 0 siblings, 1 reply; 4+ messages in thread From: David Brennan @ 2004-08-12 3:10 UTC (permalink / raw) To: eCos Discussion List I am currently having a problem with FreeBSD sockets. Setup: i386-pc 82559, latest snapshot from snapshot service. Background: Our application uses a UDP communication protocol over 2 sockets. Each one is a validated half duplex channel. That is the sendSocket will receive acknowledgments of previous sends and recvSocket will send acknowledgments of previous receives. Implementation: I open two (UDP) sockets (sendSocket, and recvSocket). I then do a select on either port. Once I receive a packet, I query each socket to see if FD_ISSET. When I send a packet (from extenal host) to the second socket checked (recvSocket), the first socket returns with FD_ISSET, then my code goes into a blocking recvfrom and hangs since no data was actually on that socket.. Here are code snippets showing how the sockets are created, selected, then received. This code has worked fine in pSOS and VxWorks, so I don't think there is a fundamental problem here, unless there is some secret to eCos implementation of BSD sockets. Any help would be greatly appreciated. David Brennan // Two sockets are created (sendSocket, recvSocket): // Create the socket socketM = socket(AF_INET, SOCK_DGRAM, 0); if (socketM < 0) { FATALSYS(("Cannot create socket")); } sockAddrInT localAddr((inAddrT((ULong) INADDR_ANY)), localPortI); // Bind the socket to local address and port number int err = bind(socketM, &localAddr, sizeof(sockaddr_in)); if( err < 0 ) { str32T addrS; FATALSYS(("Can't bind socket to local IP port %s:%d", localAddr.AddrStr(addrS.CharP()), localPortI )); } // Sockets are waited on for receive data (infinite wait): fd_set readMask; FD_ZERO(&readMask); pAssert(InRange(sendSocket, 0, FD_SETSIZE-1)); // Limit to keep FD_SET from writing out of readfds pAssert(InRange(recvSocket, 0, FD_SETSIZE-1)); // Limit to keep FD_SET from writing out of readfds FD_SET(sendSocket, &readMask); FD_SET(recvSocket, &readMask); // Use select to wait for input from either the send or receive sockets long err = select(FD_SETSIZE, &readMask, NULL, NULL, NULL); if( err < 0 ) { FATALSYS(("select()=%d ", err)); return( 0 ); } // Once select() returns successfully, check each socket (sendSocket, recvSocket) for data: // Set of socket/file descriptors fd_set readfds; // Clear all socket selections from the read file descriptor set FD_ZERO(&readfds); // Select only this socket in the read file descriptor set // Limit to keep FD_SET from writing out of readfds pAssert(InOrderedRange(socketM, 0, FD_SETSIZE-1)); FD_SET(socketM, &readfds); // Create a wait timeout timeval waitTime; waitTime.tv_sec = 0L; waitTime.tv_usec = 0; // Use select on this socket to determine if there is pending read data int result = select(FD_SETSIZE, &readfds, NULL, NULL, &waitTime ); if( result < 0 ) { FATALSYS(("Error in: select(%d)", socketM)); } int isSet = FD_ISSET(socketM, &readfds); if( isSet != 0 ) { respPktT respPkt; sockAddrInT sendersAddr; recvfrom( socketM, (char *) (&respPkt), sizeof(respPkt), 0, // flags (sockaddr *) (&sendersAddr), (socklen_t) sizeof(sendersAddr) ) } Exported ecos.ecc: cdl_savefile_version 1; cdl_savefile_command cdl_savefile_version {}; cdl_savefile_command cdl_savefile_command {}; cdl_savefile_command cdl_configuration { description hardware template package }; cdl_savefile_command cdl_package { value_source user_value wizard_value inferred_value }; cdl_savefile_command cdl_component { value_source user_value wizard_value inferred_value }; cdl_savefile_command cdl_option { value_source user_value wizard_value inferred_value }; cdl_savefile_command cdl_interface { value_source user_value wizard_value inferred_value }; cdl_configuration eCos { description "" ; hardware pc ; template default ; package -hardware CYGPKG_HAL_I386 current ; package -hardware CYGPKG_HAL_I386_GENERIC current ; package -hardware CYGPKG_HAL_I386_PC current ; package -hardware CYGPKG_HAL_I386_PCMB current ; package -hardware CYGPKG_IO_PCI current ; package -hardware CYGPKG_IO_SERIAL_GENERIC_16X5X current ; package -hardware CYGPKG_IO_SERIAL_I386_PC current ; package -hardware CYGPKG_DEVS_ETH_INTEL_I82559 current ; package -hardware CYGPKG_DEVS_ETH_I386_PC_I82559 current ; package -hardware CYGPKG_DEVICES_WALLCLOCK_DALLAS_DS12887 current ; package -hardware CYGPKG_DEVICES_WALLCLOCK_I386_PC current ; package -template CYGPKG_HAL current ; package -template CYGPKG_IO current ; package -template CYGPKG_IO_SERIAL current ; package -template CYGPKG_INFRA current ; package -template CYGPKG_KERNEL current ; package -template CYGPKG_MEMALLOC current ; package -template CYGPKG_ISOINFRA current ; package -template CYGPKG_LIBC current ; package -template CYGPKG_LIBC_I18N current ; package -template CYGPKG_LIBC_SETJMP current ; package -template CYGPKG_LIBC_SIGNALS current ; package -template CYGPKG_LIBC_STARTUP current ; package -template CYGPKG_LIBC_STDIO current ; package -template CYGPKG_LIBC_STDLIB current ; package -template CYGPKG_LIBC_STRING current ; package -template CYGPKG_LIBC_TIME current ; package -template CYGPKG_LIBM current ; package -template CYGPKG_IO_WALLCLOCK current ; package -template CYGPKG_ERROR current ; package CYGPKG_BLOCK_LIB current ; package CYGPKG_IO_FILEIO current ; package CYGPKG_LINUX_COMPAT current ; package CYGPKG_FS_FAT current ; package CYGPKG_IO_ETH_DRIVERS current ; package CYGPKG_NET current ; package CYGPKG_NET_FREEBSD_STACK current ; package CYGPKG_POSIX current ; }; cdl_component CYGPKG_INFRA_DEBUG { user_value 1 }; cdl_option CYGIMP_KERNEL_SCHED_SORTED_QUEUES { inferred_value 1 }; cdl_option CYGSEM_KERNEL_SCHED_TIMESLICE_ENABLE { inferred_value 1 }; cdl_component CYGSEM_KERNEL_SCHED_ASR_SUPPORT { inferred_value 1 }; cdl_option CYGSEM_KERNEL_SCHED_ASR_GLOBAL { inferred_value 1 }; cdl_option CYGBLD_ISO_CTYPE_HEADER { inferred_value 1 <cyg/libc/i18n/ctype.inl> }; cdl_option CYGBLD_ISO_ERRNO_CODES_HEADER { inferred_value 1 <cyg/error/codes.h> }; cdl_option CYGBLD_ISO_ERRNO_HEADER { inferred_value 1 <cyg/error/errno.h> }; cdl_option CYGBLD_ISO_STDIO_FILETYPES_HEADER { inferred_value 1 <cyg/libc/stdio/stdio.h> }; cdl_option CYGBLD_ISO_STDIO_STREAMS_HEADER { inferred_value 1 <cyg/libc/stdio/stdio.h> }; cdl_option CYGBLD_ISO_STDIO_FILEOPS_HEADER { inferred_value 1 <cyg/libc/stdio/stdio.h> }; cdl_option CYGBLD_ISO_STDIO_FILEACCESS_HEADER { inferred_value 1 <cyg/libc/stdio/stdio.h> }; cdl_option CYGBLD_ISO_STDIO_FORMATTED_IO_HEADER { inferred_value 1 <cyg/libc/stdio/stdio.h> }; cdl_option CYGBLD_ISO_STDIO_CHAR_IO_HEADER { inferred_value 1 <cyg/libc/stdio/stdio.h> }; cdl_option CYGBLD_ISO_STDIO_DIRECT_IO_HEADER { inferred_value 1 <cyg/libc/stdio/stdio.h> }; cdl_option CYGBLD_ISO_STDIO_FILEPOS_HEADER { inferred_value 1 <cyg/libc/stdio/stdio.h> }; cdl_option CYGBLD_ISO_STDIO_ERROR_HEADER { inferred_value 1 <cyg/libc/stdio/stdio.h> }; cdl_option CYGBLD_ISO_STDLIB_STRCONV_HEADER { inferred_value 1 <cyg/libc/stdlib/atox.inl> }; cdl_option CYGBLD_ISO_STDLIB_ABS_HEADER { inferred_value 1 <cyg/libc/stdlib/abs.inl> }; cdl_option CYGBLD_ISO_STDLIB_DIV_HEADER { inferred_value 1 <cyg/libc/stdlib/div.inl> }; cdl_option CYGBLD_ISO_STRERROR_HEADER { inferred_value 1 <cyg/error/strerror.h> }; cdl_option CYGBLD_ISO_STRTOK_R_HEADER { inferred_value 1 <cyg/libc/string/string.h> }; cdl_option CYGBLD_ISO_STRING_LOCALE_FUNCS_HEADER { inferred_value 1 <cyg/libc/string/string.h> }; cdl_option CYGBLD_ISO_STRING_BSD_FUNCS_HEADER { inferred_value 1 <cyg/libc/string/bsdstring.h> }; cdl_option CYGBLD_ISO_STRING_MEMFUNCS_HEADER { inferred_value 1 <cyg/libc/string/string.h> }; cdl_option CYGBLD_ISO_STRING_STRFUNCS_HEADER { inferred_value 1 <cyg/libc/string/string.h> }; cdl_option CYGBLD_ISO_POSIX_CLOCK_TYPES_HEADER { inferred_value 1 <cyg/posix/time.h> }; cdl_option CYGBLD_ISO_C_TIME_TYPES_HEADER { inferred_value 1 <cyg/libc/time/time.h> }; cdl_option CYGBLD_ISO_POSIX_CLOCKS_HEADER { inferred_value 1 <cyg/posix/time.h> }; cdl_option CYGBLD_ISO_C_CLOCK_FUNCS_HEADER { inferred_value 1 <cyg/libc/time/time.h> }; cdl_option CYGBLD_ISO_SIGNAL_NUMBERS_HEADER { inferred_value 1 <cyg/libc/signals/signal.h> }; cdl_option CYGBLD_ISO_SIGNAL_IMPL_HEADER { inferred_value 1 <cyg/libc/signals/signal.h> }; cdl_option CYGBLD_ISO_SETJMP_HEADER { inferred_value 1 <cyg/libc/setjmp/setjmp.h> }; cdl_option CYGBLD_ISO_SIGSETJMP_HEADER { inferred_value 1 <cyg/posix/sigsetjmp.h> }; cdl_option CYGBLD_ISO_DIRENT_HEADER { inferred_value 1 <cyg/fileio/dirent.h> }; cdl_option CYGBLD_ISO_PTHREADTYPES_HEADER { inferred_value 1 <cyg/posix/types.h> }; cdl_option CYGBLD_ISO_PMUTEXTYPES_HEADER { inferred_value 1 <cyg/posix/muttypes.h> }; cdl_option CYGBLD_ISO_BSDTYPES_HEADER { inferred_value 1 <sys/bsdtypes.h> }; cdl_option CYGBLD_ISO_UTSNAME_HEADER { inferred_value 1 <cyg/posix/utsname.h> }; cdl_option CYGBLD_ISO_SEMAPHORES_HEADER { inferred_value 1 <cyg/posix/semaphore.h> }; cdl_option CYGBLD_ISO_PTHREAD_IMPL_HEADER { inferred_value 1 <cyg/posix/pthread.h> }; cdl_option CYGBLD_ISO_PTHREAD_MUTEX_HEADER { inferred_value 1 <cyg/posix/mutex.h> }; cdl_option CYGBLD_ISO_POSIX_LIMITS_HEADER { inferred_value 1 <cyg/posix/limits.h> }; cdl_option CYGBLD_ISO_OPEN_MAX_HEADER { inferred_value 1 <cyg/fileio/limits.h> }; cdl_option CYGBLD_ISO_NAME_MAX_HEADER { inferred_value 1 <cyg/fileio/limits.h> }; cdl_option CYGBLD_ISO_NETDB_PROTO_HEADER { inferred_value 1 <net/netdb.h> }; cdl_option CYGBLD_ISO_NETDB_SERV_HEADER { inferred_value 1 <net/netdb.h> }; cdl_option CYGPKG_POSIX_TIMERS { inferred_value 0 }; cdl_component CYGPKG_POSIX_SIGNALS { inferred_value 0 }; -- Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [ECOS] FreeBSD problem with UDP sockets 2004-08-12 3:10 [ECOS] FreeBSD problem with UDP sockets David Brennan @ 2004-08-12 8:23 ` Andrew Lunn 2004-08-13 3:45 ` David Brennan 2004-08-18 20:58 ` Bart Veer 0 siblings, 2 replies; 4+ messages in thread From: Andrew Lunn @ 2004-08-12 8:23 UTC (permalink / raw) To: David Brennan; +Cc: eCos Discussion List On Wed, Aug 11, 2004 at 08:10:46PM -0700, David Brennan wrote: > I am currently having a problem with FreeBSD sockets. > Setup: i386-pc 82559, latest snapshot from snapshot service. > > Background: Our application uses a UDP communication protocol over 2 > sockets. Each one is a validated half duplex channel. That is the > sendSocket will receive acknowledgments of previous sends and recvSocket > will send acknowledgments of previous receives. > Implementation: I open two (UDP) sockets (sendSocket, and recvSocket). > I then do a select on either port. Once I receive a packet, I query each > socket to see if FD_ISSET. When I send a packet (from extenal host) to > the second socket checked (recvSocket), the first socket returns with > FD_ISSET, then my code goes into a blocking recvfrom and hangs since no > data was actually on that socket.. > > Here are code snippets showing how the sockets are created, selected, > then received. This code has worked fine in pSOS and VxWorks, so I don't > think there is a fundamental problem here, unless there is some secret > to eCos implementation of BSD sockets. > > Any help would be greatly appreciated. > > David Brennan > > // Two sockets are created (sendSocket, recvSocket): > > // Create the socket > socketM = socket(AF_INET, SOCK_DGRAM, 0); > > if (socketM < 0) > { > FATALSYS(("Cannot create socket")); > } > > sockAddrInT localAddr((inAddrT((ULong) INADDR_ANY)), localPortI); > > // Bind the socket to local address and port number > int err = bind(socketM, &localAddr, sizeof(sockaddr_in)); > if( err < 0 ) > { > str32T addrS; > FATALSYS(("Can't bind socket to local IP port %s:%d", > localAddr.AddrStr(addrS.CharP()), > localPortI > )); > } > So the above code creates socketM. Fine. > > // Sockets are waited on for receive data (infinite wait): > > fd_set readMask; > > FD_ZERO(&readMask); > pAssert(InRange(sendSocket, 0, FD_SETSIZE-1)); // Limit to > keep FD_SET from writing out of readfds > pAssert(InRange(recvSocket, 0, FD_SETSIZE-1)); // Limit to > keep FD_SET from writing out of readfds > FD_SET(sendSocket, &readMask); > FD_SET(recvSocket, &readMask); > > // Use select to wait for input from either the send or receive > sockets > long err = select(FD_SETSIZE, &readMask, NULL, NULL, NULL); Here you are using sendSocket and recvSocket which we have not seen created. If we get passed select we know that one of these two sockets has data on them. > if( err < 0 ) > { > FATALSYS(("select()=%d ", err)); > return( 0 ); > } > > // Once select() returns successfully, check each socket (sendSocket, > recvSocket) for data: > > // Set of socket/file descriptors > fd_set readfds; > > // Clear all socket selections from the read file descriptor set > FD_ZERO(&readfds); > > // Select only this socket in the read file descriptor set > // Limit to keep FD_SET from writing out of readfds > pAssert(InOrderedRange(socketM, 0, FD_SETSIZE-1)); > FD_SET(socketM, &readfds); > > // Create a wait timeout > timeval waitTime; > waitTime.tv_sec = 0L; > waitTime.tv_usec = 0; > > // Use select on this socket to determine if there is pending read data > int result = select(FD_SETSIZE, > &readfds, > NULL, > NULL, > &waitTime > ); Now we are back to socketM. What is not clear for me is the relationship between sendSocket, recvSocket and socketM. > if( result < 0 ) > { > FATALSYS(("Error in: select(%d)", socketM)); > } > > int isSet = FD_ISSET(socketM, &readfds); Here is your problem. With passing {0,0} for waitTime, you are doing a poll. If there is nothing to receive on the socket, select will return 0, but it is not updating the readfds. Read the code in packages/io/fileio/current/src/select.cxx. This might be an eCos bug. It might not be as well. The Posix standard at not 100% clear on this issue when i read it. http://www.opengroup.org/onlinepubs/009695399/toc.htm On failure, the objects pointed to by the readfds, writefds, and errorfds arguments shall not be modified. If the timeout interval expires without the specified condition being true for any of the specified file descriptors, the objects pointed to by the readfds, writefds, and errorfds arguments shall have all bits set to 0. When you have passed a timeout of {0,0} you are doing a poll. So the timeout has not expired. However, we are not returning an error code so it could also be said we are not in the failure case either. To make your code work with eCos, check to see if the return value is > 0. > > if( isSet != 0 ) > { > respPktT respPkt; > sockAddrInT sendersAddr; > > recvfrom( socketM, > (char *) (&respPkt), > sizeof(respPkt), > 0, // flags > (sockaddr *) (&sendersAddr), > (socklen_t) sizeof(sendersAddr) > ) > } Andrew -- Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [ECOS] FreeBSD problem with UDP sockets 2004-08-12 8:23 ` Andrew Lunn @ 2004-08-13 3:45 ` David Brennan 2004-08-18 20:58 ` Bart Veer 1 sibling, 0 replies; 4+ messages in thread From: David Brennan @ 2004-08-13 3:45 UTC (permalink / raw) To: Andrew Lunn; +Cc: eCos Discussion List Thanks Andrew, that did the trick. I'm still not sure it is "correct". But I'm not an expert at interpreting standards. David Brennan Andrew Lunn wrote: >On Wed, Aug 11, 2004 at 08:10:46PM -0700, David Brennan wrote: > > >>I am currently having a problem with FreeBSD sockets. >>Setup: i386-pc 82559, latest snapshot from snapshot service. >> >>Background: Our application uses a UDP communication protocol over 2 >>sockets. Each one is a validated half duplex channel. That is the >>sendSocket will receive acknowledgments of previous sends and recvSocket >>will send acknowledgments of previous receives. >>Implementation: I open two (UDP) sockets (sendSocket, and recvSocket). >>I then do a select on either port. Once I receive a packet, I query each >>socket to see if FD_ISSET. When I send a packet (from extenal host) to >>the second socket checked (recvSocket), the first socket returns with >>FD_ISSET, then my code goes into a blocking recvfrom and hangs since no >>data was actually on that socket.. >> >>Here are code snippets showing how the sockets are created, selected, >>then received. This code has worked fine in pSOS and VxWorks, so I don't >>think there is a fundamental problem here, unless there is some secret >>to eCos implementation of BSD sockets. >> >>Any help would be greatly appreciated. >> >>David Brennan >> >>// Two sockets are created (sendSocket, recvSocket): >> >> // Create the socket >> socketM = socket(AF_INET, SOCK_DGRAM, 0); >> >> if (socketM < 0) >> { >> FATALSYS(("Cannot create socket")); >> } >> >> sockAddrInT localAddr((inAddrT((ULong) INADDR_ANY)), localPortI); >> >> // Bind the socket to local address and port number >> int err = bind(socketM, &localAddr, sizeof(sockaddr_in)); >> if( err < 0 ) >> { >> str32T addrS; >> FATALSYS(("Can't bind socket to local IP port %s:%d", >> localAddr.AddrStr(addrS.CharP()), >> localPortI >> )); >> } >> >> >> > >So the above code creates socketM. Fine. > > >>// Sockets are waited on for receive data (infinite wait): >> >> fd_set readMask; >> >> FD_ZERO(&readMask); >> pAssert(InRange(sendSocket, 0, FD_SETSIZE-1)); // Limit to >>keep FD_SET from writing out of readfds >> pAssert(InRange(recvSocket, 0, FD_SETSIZE-1)); // Limit to >>keep FD_SET from writing out of readfds >> FD_SET(sendSocket, &readMask); >> FD_SET(recvSocket, &readMask); >> >> // Use select to wait for input from either the send or receive >>sockets >> long err = select(FD_SETSIZE, &readMask, NULL, NULL, NULL); >> >> > >Here you are using sendSocket and recvSocket which we have not seen >created. If we get passed select we know that one of these two sockets >has data on them. > > > > >> if( err < 0 ) >> { >> FATALSYS(("select()=%d ", err)); >> return( 0 ); >> } >> >>// Once select() returns successfully, check each socket (sendSocket, >>recvSocket) for data: >> >> // Set of socket/file descriptors >> fd_set readfds; >> >> // Clear all socket selections from the read file descriptor set >> FD_ZERO(&readfds); >> >> // Select only this socket in the read file descriptor set >> // Limit to keep FD_SET from writing out of readfds >> pAssert(InOrderedRange(socketM, 0, FD_SETSIZE-1)); >> FD_SET(socketM, &readfds); >> >> // Create a wait timeout >> timeval waitTime; >> waitTime.tv_sec = 0L; >> waitTime.tv_usec = 0; >> >> // Use select on this socket to determine if there is pending read data >> int result = select(FD_SETSIZE, >> &readfds, >> NULL, >> NULL, >> &waitTime >> ); >> >> > >Now we are back to socketM. > >What is not clear for me is the relationship between sendSocket, >recvSocket and socketM. > > > >> if( result < 0 ) >> { >> FATALSYS(("Error in: select(%d)", socketM)); >> } >> >> int isSet = FD_ISSET(socketM, &readfds); >> >> > >Here is your problem. With passing {0,0} for waitTime, you are doing a >poll. If there is nothing to receive on the socket, select will return >0, but it is not updating the readfds. Read the code in >packages/io/fileio/current/src/select.cxx. > >This might be an eCos bug. It might not be as well. The Posix >standard at not 100% clear on this issue when i read >it. http://www.opengroup.org/onlinepubs/009695399/toc.htm > > On failure, the objects pointed to by the readfds, writefds, and > errorfds arguments shall not be modified. If the timeout interval > expires without the specified condition being true for any of the > specified file descriptors, the objects pointed to by the readfds, > writefds, and errorfds arguments shall have all bits set to 0. > >When you have passed a timeout of {0,0} you are doing a poll. So the >timeout has not expired. However, we are not returning an error code >so it could also be said we are not in the failure case either. > >To make your code work with eCos, check to see if the return value is > > >>0. >> >> > > > > >> if( isSet != 0 ) >> { >> respPktT respPkt; >> sockAddrInT sendersAddr; >> >> recvfrom( socketM, >> (char *) (&respPkt), >> sizeof(respPkt), >> 0, // flags >> (sockaddr *) (&sendersAddr), >> (socklen_t) sizeof(sendersAddr) >> ) >> } >> >> > > > Andrew > > > -- Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [ECOS] FreeBSD problem with UDP sockets 2004-08-12 8:23 ` Andrew Lunn 2004-08-13 3:45 ` David Brennan @ 2004-08-18 20:58 ` Bart Veer 1 sibling, 0 replies; 4+ messages in thread From: Bart Veer @ 2004-08-18 20:58 UTC (permalink / raw) To: andrew; +Cc: eCos, ecos-discuss >>>>> "Andrew" == Andrew Lunn <andrew@lunn.ch> writes: >> if( result < 0 ) >> { >> FATALSYS(("Error in: select(%d)", socketM)); >> } >> >> int isSet = FD_ISSET(socketM, &readfds); Andrew> Here is your problem. With passing {0,0} for waitTime, you Andrew> are doing a poll. If there is nothing to receive on the Andrew> socket, select will return 0, but it is not updating the Andrew> readfds. Read the code in Andrew> packages/io/fileio/current/src/select.cxx. Andrew> This might be an eCos bug. It might not be as well. The Posix Andrew> standard at not 100% clear on this issue when i read Andrew> it. http://www.opengroup.org/onlinepubs/009695399/toc.htm Andrew> On failure, the objects pointed to by the readfds, writefds, and Andrew> errorfds arguments shall not be modified. If the timeout interval Andrew> expires without the specified condition being true for any of the Andrew> specified file descriptors, the objects pointed to by the readfds, Andrew> writefds, and errorfds arguments shall have all bits set to 0. Andrew> When you have passed a timeout of {0,0} you are doing a Andrew> poll. So the timeout has not expired. However, we are not Andrew> returning an error code so it could also be said we are Andrew> not in the failure case either. From my reading of the standard, specifically the "Return Value" section, a poll is not a failure condition: Upon successful completion, the pselect() and select() functions shall return the total number of bits set in the bit masks. Otherwise, -1 shall be returned, and errno shall be set to indicate the error. Since in this case we are not returning -1 it is not a failure, and hence the fd_sets should be cleared. There is also some relevant text in the Linux select_tut man page: If select timed out, then the file descriptors sets should be all empty (but may not be on some systems). However the return value will definitely be zero. That man page is not authorative, but does suggest that clearing the fd_sets is the right thing to do even though not all systems work that way. I think the current eCos behaviour is actually more sensible because it means you only need to reset the fd_sets when there has been I/O, not after every unsuccessful poll. But the standard says otherwise. The following (untested) would probably fix the problem, but I'll leave it to Nick to decide what to about it. Bart Index: select.cxx =================================================================== RCS file: /cvs/ecos/ecos/packages/io/fileio/current/src/select.cxx,v retrieving revision 1.12 diff -u -r1.12 select.cxx --- select.cxx 2 Aug 2004 11:24:48 -0000 1.12 +++ select.cxx 18 Aug 2004 20:54:16 -0000 @@ -206,7 +206,7 @@ if( error ) break; - if (num) + if (num || (0 == ticks)) { // Found something, update user's sets if (in) FD_COPY( &in_res, in ); @@ -248,13 +248,6 @@ // Nothing found, see if we want to wait if (tv) { - // Special case of "poll" - if (ticks == 0) - { - error = EAGAIN; - break; - } - ticks += Cyg_Clock::real_time_clock->current_value(); if( !selwait.wait( ticks ) ) -- Bart Veer eCos Configuration Architect http://www.ecoscentric.com/ The eCos and RedBoot experts -- Before posting, please read the FAQ: http://ecos.sourceware.org/fom/ecos and search the list archive: http://ecos.sourceware.org/ml/ecos-discuss ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2004-08-18 20:58 UTC | newest] Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2004-08-12 3:10 [ECOS] FreeBSD problem with UDP sockets David Brennan 2004-08-12 8:23 ` Andrew Lunn 2004-08-13 3:45 ` David Brennan 2004-08-18 20:58 ` Bart Veer
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).