Merge branch 'bugfix/select_init_sem_v3.2' into 'release/v3.2'

VFS: Allocate socket select semaphore outside ISR (backport v3.2)

See merge request espressif/esp-idf!4989
This commit is contained in:
Angus Gratton 2019-07-31 16:11:57 +08:00
commit 6510c6f495
3 changed files with 21 additions and 0 deletions

View File

@ -40,6 +40,14 @@ static void lwip_stop_socket_select_isr(BaseType_t *woken)
}
}
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));
@ -61,6 +69,7 @@ void esp_vfs_lwip_sockets_register()
.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,

View File

@ -221,6 +221,8 @@ typedef struct
/** 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;

View File

@ -838,6 +838,16 @@ int esp_vfs_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errorfds
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;