fix goldfish_pipe poll error

when multiple processes call poll and a event occured,
all the processes are waked up. it should wake up one
process based on pipe->id

Signed-off-by: zhanghu5 <zhanghu5@xiaomi.com>
This commit is contained in:
zhanghu5 2023-10-08 10:24:42 +08:00 committed by Xiang Xiao
parent e793a741cc
commit 9642d8dae6
1 changed files with 9 additions and 16 deletions

View File

@ -487,7 +487,6 @@ static int goldfish_pipe_poll(FAR struct file *filp,
pollevent_t mask = 0; pollevent_t mask = 0;
int status; int status;
int i;
int ret; int ret;
ret = nxmutex_lock(&dev->polllock); ret = nxmutex_lock(&dev->polllock);
@ -498,17 +497,7 @@ static int goldfish_pipe_poll(FAR struct file *filp,
if (setup) if (setup)
{ {
for (i = 0; i < dev->pipes_capacity; i++) if (dev->fds[pipe->id] != NULL)
{
if (!dev->fds[i])
{
dev->fds[i] = fds;
fds->priv = &dev->fds[i];
break;
}
}
if (i >= dev->pipes_capacity)
{ {
fds->priv = NULL; fds->priv = NULL;
ret = -EBUSY; ret = -EBUSY;
@ -521,6 +510,9 @@ static int goldfish_pipe_poll(FAR struct file *filp,
return -ERESTART; return -ERESTART;
} }
dev->fds[pipe->id] = fds;
fds->priv = &dev->fds[pipe->id];
if (status & PIPE_POLL_IN) if (status & PIPE_POLL_IN)
mask |= EPOLLIN | EPOLLRDNORM; mask |= EPOLLIN | EPOLLRDNORM;
if (status & PIPE_POLL_OUT) if (status & PIPE_POLL_OUT)
@ -531,7 +523,7 @@ static int goldfish_pipe_poll(FAR struct file *filp,
mask |= EPOLLERR; mask |= EPOLLERR;
if (mask) if (mask)
poll_notify(dev->fds, dev->pipes_capacity, mask); poll_notify(&fds, 1, mask);
} }
else if (fds->priv != NULL) else if (fds->priv != NULL)
{ {
@ -663,13 +655,13 @@ static void goldfish_interrupt_task(FAR void *arg)
if (nxmutex_lock(&dev->polllock) == OK) if (nxmutex_lock(&dev->polllock) == OK)
{ {
if (wakes & PIPE_WAKE_READ) if (wakes & PIPE_WAKE_READ)
poll_notify(dev->fds, dev->pipes_capacity, EPOLLIN); poll_notify(&dev->fds[pipe->id], 1, EPOLLIN);
if (wakes & PIPE_WAKE_WRITE) if (wakes & PIPE_WAKE_WRITE)
poll_notify(dev->fds, dev->pipes_capacity, EPOLLOUT); poll_notify(&dev->fds[pipe->id], 1, EPOLLOUT);
if (wakes & PIPE_WAKE_CLOSED) if (wakes & PIPE_WAKE_CLOSED)
poll_notify(dev->fds, dev->pipes_capacity, EPOLLHUP); poll_notify(&dev->fds[pipe->id], 1, EPOLLHUP);
nxmutex_unlock(&dev->polllock); nxmutex_unlock(&dev->polllock);
} }
@ -876,6 +868,7 @@ static int goldfish_pipe_release(FAR struct file *filp)
flags = spin_lock_irqsave(&dev->lock); flags = spin_lock_irqsave(&dev->lock);
dev->pipes[pipe->id] = NULL; dev->pipes[pipe->id] = NULL;
dev->fds[pipe->id] = NULL;
signalled_pipes_remove_locked(dev, pipe); signalled_pipes_remove_locked(dev, pipe);
spin_unlock_irqrestore(&dev->lock, flags); spin_unlock_irqrestore(&dev->lock, flags);