VFS: Allocate socket select semaphore outside ISR

This commit is contained in:
Roland Dobai 2019-04-01 12:50:54 +02:00
parent eae386d0db
commit 7307bf1b87
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) static int lwip_fcntl_r_wrapper(int fd, int cmd, va_list args)
{ {
return lwip_fcntl_r(fd, cmd, va_arg(args, int)); return lwip_fcntl_r(fd, cmd, va_arg(args, int));
@ -61,6 +69,7 @@ void esp_vfs_lwip_sockets_register()
.read = &lwip_read_r, .read = &lwip_read_r,
.fcntl = &lwip_fcntl_r_wrapper, .fcntl = &lwip_fcntl_r_wrapper,
.ioctl = &lwip_ioctl_r_wrapper, .ioctl = &lwip_ioctl_r_wrapper,
.get_socket_select_semaphore = &lwip_get_socket_select_semaphore,
.socket_select = &lwip_select, .socket_select = &lwip_select,
.stop_socket_select = &lwip_stop_socket_select, .stop_socket_select = &lwip_stop_socket_select,
.stop_socket_select_isr = &lwip_stop_socket_select_isr, .stop_socket_select_isr = &lwip_stop_socket_select_isr,

View file

@ -187,6 +187,8 @@ typedef struct
/** stop_socket_select which can be called from ISR; set only for the socket driver */ /** stop_socket_select which can be called from ISR; set only for the socket driver */
void (*stop_socket_select_isr)(BaseType_t *woken); 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 */ /** 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)(); void (*end_select)();
} esp_vfs_t; } 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)) { esp_vfs_safe_fd_isset(fd, errorfds)) {
const vfs_entry_t *vfs = s_vfs[vfs_index]; const vfs_entry_t *vfs = s_vfs[vfs_index];
socket_select = vfs->vfs.socket_select; 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; continue;