int poll(FAR struct pollfd *fds, nfds_t nfds, int timeout) { WDOG_ID wdog; sem_t sem; int count = 0; int ret; sem_init(&sem, 0, 0); ret = poll_setup(fds, nfds, &sem); if (ret >= 0) { if (timeout >= 0) { /* Wait for the poll event with a timeout. Note that the * millisecond timeout has to be converted to system clock * ticks for wd_start */ wdog = wd_create(); wd_start(wdog, MSEC2TICK(timeout), poll_timeout, 1, (uint32_t)&sem); poll_semtake(&sem); wd_delete(wdog); } else { /* Wait for the poll event with no timeout */ poll_semtake(&sem); } /* Teardown the poll operation and get the count of events */ ret = poll_teardown(fds, nfds, &count); } sem_destroy(&sem); /* Check for errors */ if (ret < 0) { set_errno(-ret); return ERROR; } return count; }
int poll(FAR struct pollfd *fds, nfds_t nfds, int timeout) { struct timespec abstime; irqstate_t flags; sem_t sem; int count = 0; int ret; sem_init(&sem, 0, 0); ret = poll_setup(fds, nfds, &sem); if (ret >= 0) { if (timeout == 0) { /* Poll returns immediately whether we have a poll event or not. */ } else if (timeout > 0) { time_t sec; uint32_t nsec; /* Either wait for either a poll event(s) to occur or for the * specified timeout to elapse with no event. * * NOTE: If a poll event is pending (i.e., the semaphore has already * been incremented), sem_timedwait() will not wait, but will return * immediately. */ sec = timeout / MSEC_PER_SEC; nsec = (timeout - MSEC_PER_SEC * sec) * NSEC_PER_MSEC; /* Make sure that the following are atomic by disabling interrupts. * Interrupts will be re-enabled while we are waiting. */ flags = irqsave(); (void)clock_gettime(CLOCK_REALTIME, &abstime); abstime.tv_sec += sec; abstime.tv_nsec += nsec; if (abstime.tv_nsec > NSEC_PER_SEC) { abstime.tv_sec++; abstime.tv_nsec -= NSEC_PER_SEC; } (void)sem_timedwait(&sem, &abstime); irqrestore(flags); } else { /* Wait for the poll event with no timeout */ poll_semtake(&sem); } /* Teardown the poll operation and get the count of events. Zero will be * returned in the case of a timeout. */ ret = poll_teardown(fds, nfds, &count); } sem_destroy(&sem); /* Check for errors */ if (ret < 0) { set_errno(-ret); return ERROR; } return count; }