libcamera: event_dispatcher_poll: Handle interrupted ppoll() calls
The ppoll() call can be interrupted if a signal is delivered. Handle the EINTR error code gracefully by restarting the call. This fixes the event-dispatcher test failure. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
This commit is contained in:
parent
83c73c39c5
commit
d370c1b46e
2 changed files with 34 additions and 25 deletions
|
@ -128,6 +128,37 @@ void EventDispatcherPoll::processEvents()
|
|||
for (auto notifier : notifiers_)
|
||||
pollfds.push_back({ notifier.first, notifier.second.events(), 0 });
|
||||
|
||||
/* Wait for events and process notifiers and timers. */
|
||||
do {
|
||||
ret = poll(&pollfds);
|
||||
} while (ret == -1 && errno == EINTR);
|
||||
|
||||
if (ret < 0) {
|
||||
ret = -errno;
|
||||
LOG(Event, Warning) << "poll() failed with " << strerror(-ret);
|
||||
} else if (ret > 0) {
|
||||
processNotifiers(pollfds);
|
||||
}
|
||||
|
||||
processTimers();
|
||||
}
|
||||
|
||||
short EventDispatcherPoll::EventNotifierSetPoll::events() const
|
||||
{
|
||||
short events = 0;
|
||||
|
||||
if (notifiers[EventNotifier::Read])
|
||||
events |= POLLIN;
|
||||
if (notifiers[EventNotifier::Write])
|
||||
events |= POLLOUT;
|
||||
if (notifiers[EventNotifier::Exception])
|
||||
events |= POLLPRI;
|
||||
|
||||
return events;
|
||||
}
|
||||
|
||||
int EventDispatcherPoll::poll(std::vector<struct pollfd> *pollfds)
|
||||
{
|
||||
/* Compute the timeout. */
|
||||
Timer *nextTimer = !timers_.empty() ? timers_.front() : nullptr;
|
||||
struct timespec timeout;
|
||||
|
@ -151,31 +182,8 @@ void EventDispatcherPoll::processEvents()
|
|||
<< timeout.tv_nsec;
|
||||
}
|
||||
|
||||
/* Wait for events and process notifiers and timers. */
|
||||
ret = ppoll(pollfds.data(), pollfds.size(),
|
||||
nextTimer ? &timeout : nullptr, nullptr);
|
||||
if (ret < 0) {
|
||||
ret = -errno;
|
||||
LOG(Event, Warning) << "poll() failed with " << strerror(-ret);
|
||||
} else if (ret > 0) {
|
||||
processNotifiers(pollfds);
|
||||
}
|
||||
|
||||
processTimers();
|
||||
}
|
||||
|
||||
short EventDispatcherPoll::EventNotifierSetPoll::events() const
|
||||
{
|
||||
short events = 0;
|
||||
|
||||
if (notifiers[EventNotifier::Read])
|
||||
events |= POLLIN;
|
||||
if (notifiers[EventNotifier::Write])
|
||||
events |= POLLOUT;
|
||||
if (notifiers[EventNotifier::Exception])
|
||||
events |= POLLPRI;
|
||||
|
||||
return events;
|
||||
return ppoll(pollfds->data(), pollfds->size(),
|
||||
nextTimer ? &timeout : nullptr, nullptr);
|
||||
}
|
||||
|
||||
void EventDispatcherPoll::processNotifiers(const std::vector<struct pollfd> &pollfds)
|
||||
|
|
|
@ -41,6 +41,7 @@ private:
|
|||
std::map<int, EventNotifierSetPoll> notifiers_;
|
||||
std::list<Timer *> timers_;
|
||||
|
||||
int poll(std::vector<struct pollfd> *pollfds);
|
||||
void processNotifiers(const std::vector<struct pollfd> &pollfds);
|
||||
void processTimers();
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue