@@ -60,32 +60,35 @@ STATIC void socket_select_task(void *arg) {
60
60
FD_SET (socket_change_fd , & errfds );
61
61
int max_fd = socket_change_fd ;
62
62
for (size_t i = 0 ; i < MP_ARRAY_SIZE (open_socket_fds ); i ++ ) {
63
- if (open_socket_fds [i ] < 0 ) {
63
+ int sockfd = open_socket_fds [i ];
64
+ if (sockfd < 0 ) {
64
65
continue ;
65
66
}
66
- max_fd = MAX (max_fd , open_socket_fds [ i ] );
67
- FD_SET (open_socket_fds [ i ] , & readfds );
68
- FD_SET (open_socket_fds [ i ] , & errfds );
67
+ max_fd = MAX (max_fd , sockfd );
68
+ FD_SET (sockfd , & readfds );
69
+ FD_SET (sockfd , & errfds );
69
70
}
70
71
71
72
int num_triggered = select (max_fd + 1 , & readfds , NULL , & errfds , NULL );
72
- if (num_triggered < 0 ) {
73
- // Maybe bad file descriptor
74
- for (size_t i = 0 ; i < MP_ARRAY_SIZE (open_socket_fds ); i ++ ) {
75
- int sockfd = open_socket_fds [i ];
76
- if (sockfd < 0 ) {
77
- continue ;
78
- }
79
- if (FD_ISSET (sockfd , & errfds )) {
80
- int err ;
81
- int optlen = sizeof (int );
82
- int ret = getsockopt (sockfd , SOL_SOCKET , SO_ERROR , & err , (socklen_t * )& optlen );
83
- if (ret < 0 ) {
84
- open_socket_fds [i ] = -1 ;
85
- // Try again.
86
- continue ;
87
- }
88
- }
73
+ // Check for bad file descriptor and queue up the background task before
74
+ // circling around.
75
+ if (num_triggered == -1 && errno == EBADF ) {
76
+ // One for the change fd and one for the closed socket.
77
+ num_triggered = 2 ;
78
+ }
79
+ // Try and find the bad file and remove it from monitoring.
80
+ for (size_t i = 0 ; i < MP_ARRAY_SIZE (open_socket_fds ); i ++ ) {
81
+ int sockfd = open_socket_fds [i ];
82
+ if (sockfd < 0 ) {
83
+ continue ;
84
+ }
85
+ int err ;
86
+ int optlen = sizeof (int );
87
+ int ret = getsockopt (sockfd , SOL_SOCKET , SO_ERROR , & err , (socklen_t * )& optlen );
88
+ if (ret < 0 ) {
89
+ open_socket_fds [i ] = -1 ;
90
+ // Raise num_triggered so that we skip the assert and queue the background task.
91
+ num_triggered = 2 ;
89
92
}
90
93
}
91
94
assert (num_triggered >= 0 );
@@ -117,13 +120,13 @@ void socket_user_reset(void) {
117
120
user_socket [i ] = false;
118
121
}
119
122
socket_change_fd = eventfd (0 , 0 );
120
- // This task runs at a lower priority than CircuitPython and is used to wake CircuitPython
121
- // up when any open sockets have data to read. It allows us to sleep otherwise .
123
+ // Run this at the same priority as CP so that the web workflow background task can be
124
+ // queued while CP is running. Both tasks can still sleep and, therefore, sleep overall .
122
125
(void )xTaskCreateStaticPinnedToCore (socket_select_task ,
123
126
"socket_select" ,
124
127
2 * configMINIMAL_STACK_SIZE ,
125
128
NULL ,
126
- 0 , // Run this at IDLE priority. We only need it when CP isn't running (at 1).
129
+ uxTaskPriorityGet ( NULL ),
127
130
socket_select_stack ,
128
131
& socket_select_task_handle ,
129
132
xPortGetCoreID ());
0 commit comments