mirror of
https://github.com/espressif/esp-idf.git
synced 2025-12-10 18:06:29 +00:00
VFS: Support concurrent VFS select calls
Closes https://github.com/espressif/esp-idf/issues/3392
This commit is contained in:
@@ -794,13 +794,16 @@ int truncate(const char *path, off_t length)
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void call_end_selects(int end_index, const fds_triple_t *vfs_fds_triple)
|
||||
static void call_end_selects(int end_index, const fds_triple_t *vfs_fds_triple, void **driver_args)
|
||||
{
|
||||
for (int i = 0; i < end_index; ++i) {
|
||||
const vfs_entry_t *vfs = get_vfs_for_index(i);
|
||||
const fds_triple_t *item = &vfs_fds_triple[i];
|
||||
if (vfs && vfs->vfs.end_select && item->isset) {
|
||||
vfs->vfs.end_select();
|
||||
esp_err_t err = vfs->vfs.end_select(driver_args[i]);
|
||||
if (err != ESP_OK) {
|
||||
ESP_LOGD(TAG, "end_select failed: %s", esp_err_to_name(err));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -947,6 +950,15 @@ int esp_vfs_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errorfds
|
||||
}
|
||||
}
|
||||
|
||||
void **driver_args = calloc(s_vfs_count, sizeof(void *));
|
||||
|
||||
if (driver_args == NULL) {
|
||||
free(vfs_fds_triple);
|
||||
__errno_r(r) = ENOMEM;
|
||||
ESP_LOGD(TAG, "calloc is unsuccessful for driver args");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (int i = 0; i < s_vfs_count; ++i) {
|
||||
const vfs_entry_t *vfs = get_vfs_for_index(i);
|
||||
fds_triple_t *item = &vfs_fds_triple[i];
|
||||
@@ -958,16 +970,18 @@ int esp_vfs_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errorfds
|
||||
esp_vfs_log_fd_set("readfds", &item->readfds);
|
||||
esp_vfs_log_fd_set("writefds", &item->writefds);
|
||||
esp_vfs_log_fd_set("errorfds", &item->errorfds);
|
||||
esp_err_t err = vfs->vfs.start_select(nfds, &item->readfds, &item->writefds, &item->errorfds, sel_sem);
|
||||
esp_err_t err = vfs->vfs.start_select(nfds, &item->readfds, &item->writefds, &item->errorfds, sel_sem,
|
||||
driver_args + i);
|
||||
|
||||
if (err != ESP_OK) {
|
||||
call_end_selects(i, vfs_fds_triple);
|
||||
call_end_selects(i, vfs_fds_triple, driver_args);
|
||||
(void) set_global_fd_sets(vfs_fds_triple, s_vfs_count, readfds, writefds, errorfds);
|
||||
if (sel_sem.is_sem_local && sel_sem.sem) {
|
||||
vSemaphoreDelete(sel_sem.sem);
|
||||
sel_sem.sem = NULL;
|
||||
}
|
||||
free(vfs_fds_triple);
|
||||
free(driver_args);
|
||||
__errno_r(r) = EINTR;
|
||||
ESP_LOGD(TAG, "start_select failed: %s", esp_err_to_name(err));
|
||||
return -1;
|
||||
@@ -1006,7 +1020,7 @@ int esp_vfs_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errorfds
|
||||
xSemaphoreTake(sel_sem.sem, ticks_to_wait);
|
||||
}
|
||||
|
||||
call_end_selects(s_vfs_count, vfs_fds_triple); // for VFSs for start_select was called before
|
||||
call_end_selects(s_vfs_count, vfs_fds_triple, driver_args); // for VFSs for start_select was called before
|
||||
if (ret >= 0) {
|
||||
ret += set_global_fd_sets(vfs_fds_triple, s_vfs_count, readfds, writefds, errorfds);
|
||||
}
|
||||
@@ -1015,6 +1029,7 @@ int esp_vfs_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *errorfds
|
||||
sel_sem.sem = NULL;
|
||||
}
|
||||
free(vfs_fds_triple);
|
||||
free(driver_args);
|
||||
|
||||
ESP_LOGD(TAG, "esp_vfs_select returns %d", ret);
|
||||
esp_vfs_log_fd_set("readfds", readfds);
|
||||
|
||||
Reference in New Issue
Block a user