-
Notifications
You must be signed in to change notification settings - Fork 174
Description
Describe the bug
The select() and nx_bsd_select_wakeup() functions uses the same nx_bsd_fd_set structures to 1) filter which sockets and events select() should wait on and 2) store the resulting active sockets. For multiple sockets and events requested in select(), only the active socket is updated in the event lists (the socket is removed for unraised events). The status of other sockets will remain active for events not part of the wakeup event(s), because they remain in the state in which they were set up in the select() request. This causes spurious events to occur for the non-active sockets.
Please also mention any information which could help others to understand
the problem you're facing:
- What target device are you using? STM32H7
- Which version of Eclipse ThreadX? 6.2.0, but also applies to the latest version (6.4.3)
- What toolchain and environment? IAR Windows
- What have you tried to diagnose or workaround this issue? Debug logging, limit event filters, polling instead of passing a timeout to
select()
To Reproduce
Steps to reproduce the behavior:
- Call
select()for two sockets ("Socket 1" and "Socket 2"), each included in thereadfdsandexceptfdsdescriptors:
nx_bsd_fd_set readset, exceptset;
struct timeval tv;
NX_BSD_FD_ZERO(&readset);
NX_BSD_FD_ZERO(&exceptset);
NX_BSD_FD_SET(NX_BSD_SOCKFD_START, &readset); // socket 1
NX_BSD_FD_SET(NX_BSD_SOCKFD_START, &exceptset);
NX_BSD_FD_SET(NX_BSD_SOCKFD_START+1, &readset); // socket 2
NX_BSD_FD_SET(NX_BSD_SOCKFD_START+1, &exceptset);
tv.tv_sec = 1;
tv.tv_usec = 0;
select(3, &readset, NULL, &exceptset, &tv);
select() sets up suspend_request.nx_bsd_socket_suspend_read_fd_set and suspend_request.nx_bsd_socket_suspend_exception_fd_set with both of the sockets selected for each.
- Trigger
nx_bsd_select_wakeup()for Socket 1, for a socket read event:
nx_bsd_select_wakeup(0, FDSET_READ);
This function resets suspend_request.nx_bsd_socket_suspend_read_fd_set to include only Socket 1 (excluding Socket 2, which is good because it isn't active). Socket 1 is also cleared from suspend_request.nx_bsd_socket_suspend_exception_fd_set, since the FDSET_EXCEPTION flag was not passed into the wakeup function. However, Socket 2 is NOT cleared from the exception fd_set! It remains set from when the select() set up the event filters.
select()is woken with multiple events indicated:
a.suspend_request.nx_bsd_socket_suspend_read_fd_set=> Socket 1 active (good)
b.suspend_request.nx_bsd_socket_suspend_exception_fd_set=> Socket 2 active (bad!)
Expected behavior
The only socket returned in the suspend_request fd_set structures should be the one that nx_bsd_select_wakeup() was called for and for the event raised (Socket 1 READ).
Impact
Significant workaround required - I had to resort to polling select() in non-blocking mode instead of being able to use event-driven programming. This uses excessive processing time.
Logs and console output
Additional context
This was forked from #364
Metadata
Metadata
Assignees
Labels
Type
Projects
Status