}
}
+static void *lwip_get_socket_select_semaphore()
+{
+ /* Calling this from the same process as select() will ensure that the semaphore won't be allocated from
+ * ISR (lwip_stop_socket_select_isr).
+ */
+ return (void *) sys_thread_sem_get();
+}
+
static int lwip_fcntl_r_wrapper(int fd, int cmd, va_list args)
{
return lwip_fcntl_r(fd, cmd, va_arg(args, int));
.read = &lwip_read_r,
.fcntl = &lwip_fcntl_r_wrapper,
.ioctl = &lwip_ioctl_r_wrapper,
+ .get_socket_select_semaphore = &lwip_get_socket_select_semaphore,
.socket_select = &lwip_select,
.stop_socket_select = &lwip_stop_socket_select,
.stop_socket_select_isr = &lwip_stop_socket_select_isr,
/** stop_socket_select which can be called from ISR; set only for the socket driver */
void (*stop_socket_select_isr)(BaseType_t *woken);
/** end_select is called to stop the I/O multiplexing and deinitialize the environment created by start_select for the given VFS */
+ void* (*get_socket_select_semaphore)();
+ /** get_socket_select_semaphore returns semaphore allocated in the socket driver; set only for the socket driver */
void (*end_select)();
} esp_vfs_t;
esp_vfs_safe_fd_isset(fd, errorfds)) {
const vfs_entry_t *vfs = s_vfs[vfs_index];
socket_select = vfs->vfs.socket_select;
+
+ // get_socket_select_semaphore needs to be set for a socket driver where semaphore can be
+ // initialized outside interrupt handlers (ignoring this could result in unexpected failures)
+ if (vfs->vfs.get_socket_select_semaphore != NULL) {
+ vfs->vfs.get_socket_select_semaphore(); // Semaphore is returned and it was allocated if it
+ // wasn't before. We don't use the return value just need to be sure that it doesn't get
+ // allocated later from ISR.
+ // Note: ESP-IDF v4.0 will start to use this callback differently with some breaking changes
+ // in the VFS API.
+ }
}
}
continue;