qemu/hw/dataplane/event-poll.c
Paolo Bonzini 83c9f4ca79 hw: include hw header files with full paths
Done with this script:

cd hw
for i in `find . -name '*.h' | sed 's/^..//'`; do
  echo '\,^#.*include.*["<]'$i'[">], s,'$i',hw/&,'
done | sed -i -f - `find . -type f`

This is so that paths remain valid as files are moved.

Instead, files in hw/dataplane are referenced with the relative path.
We know they are not going to move to include/, and they are the only
include files that are in subdirectories _and_ move.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2013-03-01 15:01:17 +01:00

101 lines
2.6 KiB
C

/*
* Event loop with file descriptor polling
*
* Copyright 2012 IBM, Corp.
* Copyright 2012 Red Hat, Inc. and/or its affiliates
*
* Authors:
* Stefan Hajnoczi <stefanha@redhat.com>
*
* This work is licensed under the terms of the GNU GPL, version 2 or later.
* See the COPYING file in the top-level directory.
*
*/
#include <sys/epoll.h>
#include "event-poll.h"
/* Add an event notifier and its callback for polling */
void event_poll_add(EventPoll *poll, EventHandler *handler,
EventNotifier *notifier, EventCallback *callback)
{
struct epoll_event event = {
.events = EPOLLIN,
.data.ptr = handler,
};
handler->notifier = notifier;
handler->callback = callback;
if (epoll_ctl(poll->epoll_fd, EPOLL_CTL_ADD,
event_notifier_get_fd(notifier), &event) != 0) {
fprintf(stderr, "failed to add event handler to epoll: %m\n");
exit(1);
}
}
/* Event callback for stopping event_poll() */
static void handle_stop(EventHandler *handler)
{
/* Do nothing */
}
void event_poll_init(EventPoll *poll)
{
/* Create epoll file descriptor */
poll->epoll_fd = epoll_create1(EPOLL_CLOEXEC);
if (poll->epoll_fd < 0) {
fprintf(stderr, "epoll_create1 failed: %m\n");
exit(1);
}
/* Set up stop notifier */
if (event_notifier_init(&poll->stop_notifier, 0) < 0) {
fprintf(stderr, "failed to init stop notifier\n");
exit(1);
}
event_poll_add(poll, &poll->stop_handler,
&poll->stop_notifier, handle_stop);
}
void event_poll_cleanup(EventPoll *poll)
{
event_notifier_cleanup(&poll->stop_notifier);
close(poll->epoll_fd);
poll->epoll_fd = -1;
}
/* Block until the next event and invoke its callback */
void event_poll(EventPoll *poll)
{
EventHandler *handler;
struct epoll_event event;
int nevents;
/* Wait for the next event. Only do one event per call to keep the
* function simple, this could be changed later. */
do {
nevents = epoll_wait(poll->epoll_fd, &event, 1, -1);
} while (nevents < 0 && errno == EINTR);
if (unlikely(nevents != 1)) {
fprintf(stderr, "epoll_wait failed: %m\n");
exit(1); /* should never happen */
}
/* Find out which event handler has become active */
handler = event.data.ptr;
/* Clear the eventfd */
event_notifier_test_and_clear(handler->notifier);
/* Handle the event */
handler->callback(handler);
}
/* Stop event_poll()
*
* This function can be used from another thread.
*/
void event_poll_notify(EventPoll *poll)
{
event_notifier_set(&poll->stop_notifier);
}