forked from zephyrproject-rtos/zephyr
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
net: sockets: move poll implementation to zvfs
Move the implementation of zsock_poll to zvfs_poll. This allows other types of file descriptors to also make use of poll() functionality even when the network subsystem is not enabled. Additionally, it partially removes a dependency cycle between posix and networking by moving functionality into a mutual dependency. Signed-off-by: Chris Friedt <[email protected]>
- Loading branch information
Showing
15 changed files
with
276 additions
and
239 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,212 @@ | ||
/* | ||
* Copyright (c) 2017-2018 Linaro Limited | ||
* Copyright (c) 2021 Nordic Semiconductor | ||
* Copyright (c) 2023 Arm Limited (or its affiliates). All rights reserved. | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
#include <zephyr/kernel.h> | ||
#include <zephyr/internal/syscall_handler.h> | ||
#include <zephyr/sys/fdtable.h> | ||
|
||
#if defined(CONFIG_NET_SOCKETS_SOCKOPT_TLS) | ||
bool net_socket_is_tls(void *obj); | ||
#else | ||
#define net_socket_is_tls(obj) false | ||
#endif | ||
|
||
int zvfs_poll_internal(struct zvfs_pollfd *fds, int nfds, k_timeout_t timeout) | ||
{ | ||
bool retry; | ||
int ret = 0; | ||
int i; | ||
struct zvfs_pollfd *pfd; | ||
struct k_poll_event poll_events[CONFIG_ZVFS_POLL_MAX]; | ||
struct k_poll_event *pev; | ||
struct k_poll_event *pev_end = poll_events + ARRAY_SIZE(poll_events); | ||
const struct fd_op_vtable *vtable; | ||
struct k_mutex *lock; | ||
k_timepoint_t end; | ||
bool offload = false; | ||
const struct fd_op_vtable *offl_vtable = NULL; | ||
void *offl_ctx = NULL; | ||
|
||
end = sys_timepoint_calc(timeout); | ||
|
||
pev = poll_events; | ||
for (pfd = fds, i = nfds; i--; pfd++) { | ||
void *ctx; | ||
int result; | ||
|
||
/* Per POSIX, negative fd's are just ignored */ | ||
if (pfd->fd < 0) { | ||
continue; | ||
} | ||
|
||
ctx = zvfs_get_fd_obj_and_vtable(pfd->fd, &vtable, &lock); | ||
if (ctx == NULL) { | ||
/* Will set POLLNVAL in return loop */ | ||
continue; | ||
} | ||
|
||
(void)k_mutex_lock(lock, K_FOREVER); | ||
|
||
result = zvfs_fdtable_call_ioctl(vtable, ctx, ZFD_IOCTL_POLL_PREPARE, pfd, &pev, | ||
pev_end); | ||
if (result == -EALREADY) { | ||
/* If POLL_PREPARE returned with EALREADY, it means | ||
* it already detected that some socket is ready. In | ||
* this case, we still perform a k_poll to pick up | ||
* as many events as possible, but without any wait. | ||
*/ | ||
timeout = K_NO_WAIT; | ||
end = sys_timepoint_calc(timeout); | ||
result = 0; | ||
} else if (result == -EXDEV) { | ||
/* If POLL_PREPARE returned EXDEV, it means | ||
* it detected an offloaded socket. | ||
* If offloaded socket is used with native TLS, the TLS | ||
* wrapper for the offloaded poll will be used. | ||
* In case the fds array contains a mixup of offloaded | ||
* and non-offloaded sockets, the offloaded poll handler | ||
* shall return an error. | ||
*/ | ||
offload = true; | ||
if (offl_vtable == NULL || net_socket_is_tls(ctx)) { | ||
offl_vtable = vtable; | ||
offl_ctx = ctx; | ||
} | ||
|
||
result = 0; | ||
} | ||
|
||
k_mutex_unlock(lock); | ||
|
||
if (result < 0) { | ||
errno = -result; | ||
return -1; | ||
} | ||
} | ||
|
||
if (offload) { | ||
int poll_timeout; | ||
|
||
if (K_TIMEOUT_EQ(timeout, K_FOREVER)) { | ||
poll_timeout = SYS_FOREVER_MS; | ||
} else { | ||
poll_timeout = k_ticks_to_ms_floor32(timeout.ticks); | ||
} | ||
|
||
return zvfs_fdtable_call_ioctl(offl_vtable, offl_ctx, ZFD_IOCTL_POLL_OFFLOAD, fds, | ||
nfds, poll_timeout); | ||
} | ||
|
||
timeout = sys_timepoint_timeout(end); | ||
|
||
do { | ||
ret = k_poll(poll_events, pev - poll_events, timeout); | ||
/* EAGAIN when timeout expired, EINTR when cancelled (i.e. EOF) */ | ||
if (ret != 0 && ret != -EAGAIN && ret != -EINTR) { | ||
errno = -ret; | ||
return -1; | ||
} | ||
|
||
retry = false; | ||
ret = 0; | ||
|
||
pev = poll_events; | ||
for (pfd = fds, i = nfds; i--; pfd++) { | ||
void *ctx; | ||
int result; | ||
|
||
pfd->revents = 0; | ||
|
||
if (pfd->fd < 0) { | ||
continue; | ||
} | ||
|
||
ctx = zvfs_get_fd_obj_and_vtable(pfd->fd, &vtable, &lock); | ||
if (ctx == NULL) { | ||
pfd->revents = ZVFS_POLLNVAL; | ||
ret++; | ||
continue; | ||
} | ||
|
||
(void)k_mutex_lock(lock, K_FOREVER); | ||
|
||
result = zvfs_fdtable_call_ioctl(vtable, ctx, ZFD_IOCTL_POLL_UPDATE, pfd, | ||
&pev); | ||
k_mutex_unlock(lock); | ||
|
||
if (result == -EAGAIN) { | ||
retry = true; | ||
continue; | ||
} else if (result != 0) { | ||
errno = -result; | ||
return -1; | ||
} | ||
|
||
if (pfd->revents != 0) { | ||
ret++; | ||
} | ||
} | ||
|
||
if (retry) { | ||
if (ret > 0) { | ||
break; | ||
} | ||
|
||
timeout = sys_timepoint_timeout(end); | ||
|
||
if (K_TIMEOUT_EQ(timeout, K_NO_WAIT)) { | ||
break; | ||
} | ||
} | ||
} while (retry); | ||
|
||
return ret; | ||
} | ||
|
||
int z_impl_zvfs_poll(struct zvfs_pollfd *fds, int nfds, int poll_timeout) | ||
{ | ||
k_timeout_t timeout; | ||
|
||
if (poll_timeout < 0) { | ||
timeout = K_FOREVER; | ||
} else { | ||
timeout = K_MSEC(poll_timeout); | ||
} | ||
|
||
return zvfs_poll_internal(fds, nfds, timeout); | ||
} | ||
|
||
#ifdef CONFIG_USERSPACE | ||
static inline int z_vrfy_zvfs_poll(struct zvfs_pollfd *fds, int nfds, int timeout) | ||
{ | ||
struct zvfs_pollfd *fds_copy; | ||
size_t fds_size; | ||
int ret; | ||
|
||
/* Copy fds array from user mode */ | ||
if (size_mul_overflow(nfds, sizeof(struct zvfs_pollfd), &fds_size)) { | ||
errno = EFAULT; | ||
return -1; | ||
} | ||
fds_copy = k_usermode_alloc_from_copy((void *)fds, fds_size); | ||
if (!fds_copy) { | ||
errno = ENOMEM; | ||
return -1; | ||
} | ||
|
||
ret = z_impl_zvfs_poll(fds_copy, nfds, timeout); | ||
|
||
if (ret >= 0) { | ||
k_usermode_to_copy((void *)fds, fds_copy, fds_size); | ||
} | ||
k_free(fds_copy); | ||
|
||
return ret; | ||
} | ||
#include <zephyr/syscalls/zvfs_poll_mrsh.c> | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.