VFS: Allocate socket select semaphore outside ISR
This commit is contained in:
parent
eae386d0db
commit
7307bf1b87
3 changed files with 21 additions and 0 deletions
|
@ -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,
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in a new issue