poll() was not waking up from signals (for example mq_notify() events).

Signed-off-by: Jussi Kivilinna <jussi.kivilinna@haltian.com>
This commit is contained in:
Gregory Nutt
2014-11-19 09:31:51 -06:00
parent 8c28718bcb
commit 4448cc43db
+26 -13
View File
@@ -70,18 +70,29 @@
* Name: poll_semtake * Name: poll_semtake
****************************************************************************/ ****************************************************************************/
static void poll_semtake(FAR sem_t *sem) static int poll_semtake(FAR sem_t *sem)
{ {
/* Take the semaphore (perhaps waiting) */ /* Take the semaphore (perhaps waiting) */
while (sem_wait(sem) != 0) while (sem_wait(sem) < 0)
{ {
/* The only case that an error should occur here is if int err = get_errno();
* the wait was awakened by a signal.
/* The only case that an error should occur here is if the wait was
* awakened by a signal.
*/ */
ASSERT(get_errno() == EINTR); ASSERT(err == EINTR);
/* Received signal, break from poll wait. */
if (err == EINTR)
{
return -EINTR;
}
} }
return OK;
} }
/**************************************************************************** /****************************************************************************
@@ -204,11 +215,11 @@ static inline int poll_setup(FAR struct pollfd *fds, nfds_t nfds, sem_t *sem)
****************************************************************************/ ****************************************************************************/
#if CONFIG_NFILE_DESCRIPTORS > 0 #if CONFIG_NFILE_DESCRIPTORS > 0
static inline int poll_teardown(FAR struct pollfd *fds, nfds_t nfds, int *count) static inline int poll_teardown(FAR struct pollfd *fds, nfds_t nfds, int *count,
int ret)
{ {
unsigned int i; unsigned int i;
int status; int status;
int ret = OK;
/* Process each descriptor in the list */ /* Process each descriptor in the list */
@@ -294,14 +305,16 @@ int poll(FAR struct pollfd *fds, nfds_t nfds, int timeout)
if (timeout == 0) if (timeout == 0)
{ {
/* Poll returns immediately whether we have a poll event or not. */ /* Poll returns immediately whether we have a poll event or not. */
ret = OK;
} }
else if (timeout > 0) else if (timeout > 0)
{ {
time_t sec; time_t sec;
uint32_t nsec; uint32_t nsec;
/* Either wait for either a poll event(s) to occur or for the /* Either wait for either a poll event(s), for a signal to occur,
* specified timeout to elapse with no event. * or for the specified timeout to elapse with no event.
* *
* NOTE: If a poll event is pending (i.e., the semaphore has already * NOTE: If a poll event is pending (i.e., the semaphore has already
* been incremented), sem_timedwait() will not wait, but will return * been incremented), sem_timedwait() will not wait, but will return
@@ -326,21 +339,21 @@ int poll(FAR struct pollfd *fds, nfds_t nfds, int timeout)
abstime.tv_nsec -= NSEC_PER_SEC; abstime.tv_nsec -= NSEC_PER_SEC;
} }
(void)sem_timedwait(&sem, &abstime); ret = sem_timedwait(&sem, &abstime);
irqrestore(flags); irqrestore(flags);
} }
else else
{ {
/* Wait for the poll event with no timeout */ /* Wait for the poll event or signal with no timeout */
poll_semtake(&sem); ret = poll_semtake(&sem);
} }
/* Teardown the poll operation and get the count of events. Zero will be /* Teardown the poll operation and get the count of events. Zero will be
* returned in the case of a timeout. * returned in the case of a timeout.
*/ */
ret = poll_teardown(fds, nfds, &count); ret = poll_teardown(fds, nfds, &count, ret);
} }
sem_destroy(&sem); sem_destroy(&sem);