* [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).