drivers: net: nsos: update unwatched file descriptor with poll()
zsock_poll_internal() iterates through all fds to call ZFD_IOCTL_POLL_UPDATE on them. In cases when -EAGAIN is returned from one of such syscalls (which happens for example for TLS sockets when in the middle of a TLS handshake) whole fds array is iterated once again. This means that ZFD_IOCTL_POLL_UPDATE can be called more than once for a single preceding ZFD_IOCTL_POLL_PREPARE operation. This resulted in error in nsos_adapt_poll_remove() call, which was not intended to be called twice. In case ZFD_IOCTL_POLL_UPDATE is called second time, update 'revents' just by calling poll() syscall on the host (Linux) side with 0 timeout. Signed-off-by: Marcin Niestroj <m.niestroj@emb.dev>
This commit is contained in:
parent
7c506fad6b
commit
ea44e2715a
|
@ -113,6 +113,7 @@ int nsos_adapt_recvfrom(int fd, void *buf, size_t len, int flags,
|
|||
|
||||
void nsos_adapt_poll_add(struct nsos_mid_pollfd *pollfd);
|
||||
void nsos_adapt_poll_remove(struct nsos_mid_pollfd *pollfd);
|
||||
void nsos_adapt_poll_update(struct nsos_mid_pollfd *pollfd);
|
||||
|
||||
int nsos_adapt_fcntl_getfl(int fd);
|
||||
int nsos_adapt_fcntl_setfl(int fd, int flags);
|
||||
|
|
|
@ -533,6 +533,25 @@ void nsos_adapt_poll_remove(struct nsos_mid_pollfd *pollfd)
|
|||
nsos_adapt_nfds--;
|
||||
}
|
||||
|
||||
void nsos_adapt_poll_update(struct nsos_mid_pollfd *pollfd)
|
||||
{
|
||||
struct pollfd fds = {
|
||||
.fd = pollfd->fd,
|
||||
.events = pollfd->events,
|
||||
};
|
||||
int ret;
|
||||
|
||||
ret = poll(&fds, 1, 0);
|
||||
if (ret < 0) {
|
||||
nsi_print_error_and_exit("error in poll(): errno=%d\n", errno);
|
||||
return;
|
||||
}
|
||||
|
||||
if (ret > 0) {
|
||||
pollfd->revents = fds.revents;
|
||||
}
|
||||
}
|
||||
|
||||
struct nsos_addrinfo_wrap {
|
||||
struct nsos_mid_addrinfo addrinfo_mid;
|
||||
struct nsos_mid_sockaddr_storage addr_storage;
|
||||
|
|
|
@ -298,6 +298,11 @@ static int nsos_poll_update(struct nsos_socket *sock, struct zsock_pollfd *pfd,
|
|||
signaled = 0;
|
||||
flags = 0;
|
||||
|
||||
if (!sys_dnode_is_linked(&sock->node)) {
|
||||
nsos_adapt_poll_update(&sock->pollfd);
|
||||
return 0;
|
||||
}
|
||||
|
||||
nsos_adapt_poll_remove(&sock->pollfd);
|
||||
sys_dlist_remove(&sock->node);
|
||||
|
||||
|
|
Loading…
Reference in a new issue