提交 343eaa15 编写于 作者: D Daniel P. Berrange

Move event code out of the daemon/ into src/util/

The event loop implementation is used by more than just the
daemon, so move it into the shared area.

* daemon/event.c, src/util/event_poll.c: Renamed
* daemon/event.h, src/util/event_poll.h: Renamed
* tools/Makefile.am, tools/console.c, tools/virsh.c: Update
  to use new virEventPoll APIs
* daemon/mdns.c, daemon/mdns.c, daemon/Makefile.am: Update
  to use new virEventPoll APIs
上级 5d2c045c
...@@ -3,7 +3,6 @@ ...@@ -3,7 +3,6 @@
CLEANFILES = CLEANFILES =
DAEMON_SOURCES = \ DAEMON_SOURCES = \
event.c event.h \
libvirtd.c libvirtd.h \ libvirtd.c libvirtd.h \
remote.c remote.h \ remote.c remote.h \
dispatch.c dispatch.h \ dispatch.c dispatch.h \
......
...@@ -63,7 +63,7 @@ ...@@ -63,7 +63,7 @@
#include "remote_driver.h" #include "remote_driver.h"
#include "conf.h" #include "conf.h"
#include "event.h" #include "event.h"
#include "src/util/event.h" #include "event_poll.h"
#include "memory.h" #include "memory.h"
#include "stream.h" #include "stream.h"
#include "hooks.h" #include "hooks.h"
...@@ -893,7 +893,7 @@ static struct qemud_server *qemudInitialize(void) { ...@@ -893,7 +893,7 @@ static struct qemud_server *qemudInitialize(void) {
return NULL; return NULL;
} }
if (virEventInit() < 0) { if (virEventPollInit() < 0) {
VIR_ERROR0(_("Failed to initialize event system")); VIR_ERROR0(_("Failed to initialize event system"));
virMutexDestroy(&server->lock); virMutexDestroy(&server->lock);
if (virCondDestroy(&server->job) < 0) if (virCondDestroy(&server->job) < 0)
...@@ -957,12 +957,12 @@ static struct qemud_server *qemudInitialize(void) { ...@@ -957,12 +957,12 @@ static struct qemud_server *qemudInitialize(void) {
# endif # endif
#endif #endif
virEventRegisterImpl(virEventAddHandleImpl, virEventRegisterImpl(virEventPollAddHandle,
virEventUpdateHandleImpl, virEventPollUpdateHandle,
virEventRemoveHandleImpl, virEventPollRemoveHandle,
virEventAddTimeoutImpl, virEventPollAddTimeout,
virEventUpdateTimeoutImpl, virEventPollUpdateTimeout,
virEventRemoveTimeoutImpl); virEventPollRemoveTimeout);
return server; return server;
} }
...@@ -2283,7 +2283,7 @@ qemudDispatchServerEvent(int watch, int fd, int events, void *opaque) { ...@@ -2283,7 +2283,7 @@ qemudDispatchServerEvent(int watch, int fd, int events, void *opaque) {
static int qemudOneLoop(void) { static int qemudOneLoop(void) {
sig_atomic_t errors; sig_atomic_t errors;
if (virEventRunOnce() < 0) if (virEventPollRunOnce() < 0)
return -1; return -1;
/* Check for any signal handling errors and log them. */ /* Check for any signal handling errors and log them. */
......
...@@ -40,7 +40,7 @@ ...@@ -40,7 +40,7 @@
#include "libvirtd.h" #include "libvirtd.h"
#include "mdns.h" #include "mdns.h"
#include "event.h" #include "event.h"
#include "src/util/event.h" #include "event_poll.h"
#include "memory.h" #include "memory.h"
#define AVAHI_DEBUG(fmt, ...) VIR_DEBUG(fmt, __VA_ARGS__) #define AVAHI_DEBUG(fmt, ...) VIR_DEBUG(fmt, __VA_ARGS__)
...@@ -231,7 +231,7 @@ static void libvirtd_mdns_client_callback(AvahiClient *c, AvahiClientState state ...@@ -231,7 +231,7 @@ static void libvirtd_mdns_client_callback(AvahiClient *c, AvahiClientState state
static void libvirtd_mdns_watch_dispatch(int watch, int fd, int events, void *opaque) static void libvirtd_mdns_watch_dispatch(int watch, int fd, int events, void *opaque)
{ {
AvahiWatch *w = (AvahiWatch*)opaque; AvahiWatch *w = (AvahiWatch*)opaque;
int fd_events = virEventHandleTypeToPollEvent(events); int fd_events = virEventPollToNativeEvents(events);
AVAHI_DEBUG("Dispatch watch %d FD %d Event %d", watch, fd, fd_events); AVAHI_DEBUG("Dispatch watch %d FD %d Event %d", watch, fd, fd_events);
w->revents = fd_events; w->revents = fd_events;
w->callback(w, fd, fd_events, w->userdata); w->callback(w, fd, fd_events, w->userdata);
...@@ -257,7 +257,7 @@ static AvahiWatch *libvirtd_mdns_watch_new(const AvahiPoll *api ATTRIBUTE_UNUSED ...@@ -257,7 +257,7 @@ static AvahiWatch *libvirtd_mdns_watch_new(const AvahiPoll *api ATTRIBUTE_UNUSED
w->userdata = userdata; w->userdata = userdata;
AVAHI_DEBUG("New handle %p FD %d Event %d", w, w->fd, event); AVAHI_DEBUG("New handle %p FD %d Event %d", w, w->fd, event);
hEvents = virPollEventToEventHandleType(event); hEvents = virEventPollFromNativeEvents(event);
if ((w->watch = virEventAddHandle(fd, hEvents, if ((w->watch = virEventAddHandle(fd, hEvents,
libvirtd_mdns_watch_dispatch, libvirtd_mdns_watch_dispatch,
w, w,
......
...@@ -52,6 +52,7 @@ UTIL_SOURCES = \ ...@@ -52,6 +52,7 @@ UTIL_SOURCES = \
util/conf.c util/conf.h \ util/conf.c util/conf.h \
util/cgroup.c util/cgroup.h \ util/cgroup.c util/cgroup.h \
util/event.c util/event.h \ util/event.c util/event.h \
util/event_poll.c util/event_poll.h \
util/files.c util/files.h \ util/files.c util/files.h \
util/hash.c util/hash.h \ util/hash.c util/hash.h \
util/hooks.c util/hooks.h \ util/hooks.c util/hooks.h \
......
...@@ -393,6 +393,19 @@ virEventUpdateHandle; ...@@ -393,6 +393,19 @@ virEventUpdateHandle;
virEventUpdateTimeout; virEventUpdateTimeout;
# event_poll.h
virEventPollToNativeEvents;
virEventPollFromNativeEvents;
virEventPollRunOnce;
virEventPollInit;
virEventPollRemoveTimeout;
virEventPollUpdateTimeout;
virEventPollAddTimeout;
virEventPollRemoveHandle;
virEventPollUpdateHandle;
virEventPollAddHandle;
# fdstream.h # fdstream.h
virFDStreamOpen; virFDStreamOpen;
virFDStreamConnectUNIX; virFDStreamConnectUNIX;
......
...@@ -32,17 +32,17 @@ ...@@ -32,17 +32,17 @@
#include "threads.h" #include "threads.h"
#include "logging.h" #include "logging.h"
#include "event.h" #include "event_poll.h"
#include "memory.h" #include "memory.h"
#include "util.h" #include "util.h"
#include "ignore-value.h" #include "ignore-value.h"
#define EVENT_DEBUG(fmt, ...) VIR_DEBUG(fmt, __VA_ARGS__) #define EVENT_DEBUG(fmt, ...) VIR_DEBUG(fmt, __VA_ARGS__)
static int virEventInterruptLocked(void); static int virEventPollInterruptLocked(void);
/* State for a single file handle being monitored */ /* State for a single file handle being monitored */
struct virEventHandle { struct virEventPollHandle {
int watch; int watch;
int fd; int fd;
int events; int events;
...@@ -53,7 +53,7 @@ struct virEventHandle { ...@@ -53,7 +53,7 @@ struct virEventHandle {
}; };
/* State for a single timer being generated */ /* State for a single timer being generated */
struct virEventTimeout { struct virEventPollTimeout {
int timer; int timer;
int frequency; int frequency;
unsigned long long expiresAt; unsigned long long expiresAt;
...@@ -63,26 +63,26 @@ struct virEventTimeout { ...@@ -63,26 +63,26 @@ struct virEventTimeout {
int deleted; int deleted;
}; };
/* Allocate extra slots for virEventHandle/virEventTimeout /* Allocate extra slots for virEventPollHandle/virEventPollTimeout
records in this multiple */ records in this multiple */
#define EVENT_ALLOC_EXTENT 10 #define EVENT_ALLOC_EXTENT 10
/* State for the main event loop */ /* State for the main event loop */
struct virEventLoop { struct virEventPollLoop {
virMutex lock; virMutex lock;
int running; int running;
virThread leader; virThread leader;
int wakeupfd[2]; int wakeupfd[2];
size_t handlesCount; size_t handlesCount;
size_t handlesAlloc; size_t handlesAlloc;
struct virEventHandle *handles; struct virEventPollHandle *handles;
size_t timeoutsCount; size_t timeoutsCount;
size_t timeoutsAlloc; size_t timeoutsAlloc;
struct virEventTimeout *timeouts; struct virEventPollTimeout *timeouts;
}; };
/* Only have one event loop */ /* Only have one event loop */
static struct virEventLoop eventLoop; static struct virEventPollLoop eventLoop;
/* Unique ID for the next FD watch to be registered */ /* Unique ID for the next FD watch to be registered */
static int nextWatch = 1; static int nextWatch = 1;
...@@ -95,7 +95,7 @@ static int nextTimer = 1; ...@@ -95,7 +95,7 @@ static int nextTimer = 1;
* NB, it *must* be safe to call this from within a callback * NB, it *must* be safe to call this from within a callback
* For this reason we only ever append to existing list. * For this reason we only ever append to existing list.
*/ */
int virEventAddHandleImpl(int fd, int events, int virEventPollAddHandle(int fd, int events,
virEventHandleCallback cb, virEventHandleCallback cb,
void *opaque, void *opaque,
virFreeCallback ff) { virFreeCallback ff) {
...@@ -117,7 +117,7 @@ int virEventAddHandleImpl(int fd, int events, ...@@ -117,7 +117,7 @@ int virEventAddHandleImpl(int fd, int events,
eventLoop.handles[eventLoop.handlesCount].watch = watch; eventLoop.handles[eventLoop.handlesCount].watch = watch;
eventLoop.handles[eventLoop.handlesCount].fd = fd; eventLoop.handles[eventLoop.handlesCount].fd = fd;
eventLoop.handles[eventLoop.handlesCount].events = eventLoop.handles[eventLoop.handlesCount].events =
virEventHandleTypeToPollEvent(events); virEventPollToNativeEvents(events);
eventLoop.handles[eventLoop.handlesCount].cb = cb; eventLoop.handles[eventLoop.handlesCount].cb = cb;
eventLoop.handles[eventLoop.handlesCount].ff = ff; eventLoop.handles[eventLoop.handlesCount].ff = ff;
eventLoop.handles[eventLoop.handlesCount].opaque = opaque; eventLoop.handles[eventLoop.handlesCount].opaque = opaque;
...@@ -125,13 +125,13 @@ int virEventAddHandleImpl(int fd, int events, ...@@ -125,13 +125,13 @@ int virEventAddHandleImpl(int fd, int events,
eventLoop.handlesCount++; eventLoop.handlesCount++;
virEventInterruptLocked(); virEventPollInterruptLocked();
virMutexUnlock(&eventLoop.lock); virMutexUnlock(&eventLoop.lock);
return watch; return watch;
} }
void virEventUpdateHandleImpl(int watch, int events) { void virEventPollUpdateHandle(int watch, int events) {
int i; int i;
EVENT_DEBUG("Update handle w=%d e=%d", watch, events); EVENT_DEBUG("Update handle w=%d e=%d", watch, events);
...@@ -144,8 +144,8 @@ void virEventUpdateHandleImpl(int watch, int events) { ...@@ -144,8 +144,8 @@ void virEventUpdateHandleImpl(int watch, int events) {
for (i = 0 ; i < eventLoop.handlesCount ; i++) { for (i = 0 ; i < eventLoop.handlesCount ; i++) {
if (eventLoop.handles[i].watch == watch) { if (eventLoop.handles[i].watch == watch) {
eventLoop.handles[i].events = eventLoop.handles[i].events =
virEventHandleTypeToPollEvent(events); virEventPollToNativeEvents(events);
virEventInterruptLocked(); virEventPollInterruptLocked();
break; break;
} }
} }
...@@ -158,7 +158,7 @@ void virEventUpdateHandleImpl(int watch, int events) { ...@@ -158,7 +158,7 @@ void virEventUpdateHandleImpl(int watch, int events) {
* For this reason we only ever set a flag in the existing list. * For this reason we only ever set a flag in the existing list.
* Actual deletion will be done out-of-band * Actual deletion will be done out-of-band
*/ */
int virEventRemoveHandleImpl(int watch) { int virEventPollRemoveHandle(int watch) {
int i; int i;
EVENT_DEBUG("Remove handle w=%d", watch); EVENT_DEBUG("Remove handle w=%d", watch);
...@@ -175,7 +175,7 @@ int virEventRemoveHandleImpl(int watch) { ...@@ -175,7 +175,7 @@ int virEventRemoveHandleImpl(int watch) {
if (eventLoop.handles[i].watch == watch) { if (eventLoop.handles[i].watch == watch) {
EVENT_DEBUG("mark delete %d %d", i, eventLoop.handles[i].fd); EVENT_DEBUG("mark delete %d %d", i, eventLoop.handles[i].fd);
eventLoop.handles[i].deleted = 1; eventLoop.handles[i].deleted = 1;
virEventInterruptLocked(); virEventPollInterruptLocked();
virMutexUnlock(&eventLoop.lock); virMutexUnlock(&eventLoop.lock);
return 0; return 0;
} }
...@@ -190,7 +190,7 @@ int virEventRemoveHandleImpl(int watch) { ...@@ -190,7 +190,7 @@ int virEventRemoveHandleImpl(int watch) {
* NB, it *must* be safe to call this from within a callback * NB, it *must* be safe to call this from within a callback
* For this reason we only ever append to existing list. * For this reason we only ever append to existing list.
*/ */
int virEventAddTimeoutImpl(int frequency, int virEventPollAddTimeout(int frequency,
virEventTimeoutCallback cb, virEventTimeoutCallback cb,
void *opaque, void *opaque,
virFreeCallback ff) { virFreeCallback ff) {
...@@ -225,12 +225,12 @@ int virEventAddTimeoutImpl(int frequency, ...@@ -225,12 +225,12 @@ int virEventAddTimeoutImpl(int frequency,
eventLoop.timeoutsCount++; eventLoop.timeoutsCount++;
ret = nextTimer-1; ret = nextTimer-1;
virEventInterruptLocked(); virEventPollInterruptLocked();
virMutexUnlock(&eventLoop.lock); virMutexUnlock(&eventLoop.lock);
return ret; return ret;
} }
void virEventUpdateTimeoutImpl(int timer, int frequency) { void virEventPollUpdateTimeout(int timer, int frequency) {
struct timeval tv; struct timeval tv;
int i; int i;
EVENT_DEBUG("Updating timer %d timeout with %d ms freq", timer, frequency); EVENT_DEBUG("Updating timer %d timeout with %d ms freq", timer, frequency);
...@@ -252,7 +252,7 @@ void virEventUpdateTimeoutImpl(int timer, int frequency) { ...@@ -252,7 +252,7 @@ void virEventUpdateTimeoutImpl(int timer, int frequency) {
frequency >= 0 ? frequency + frequency >= 0 ? frequency +
(((unsigned long long)tv.tv_sec)*1000) + (((unsigned long long)tv.tv_sec)*1000) +
(((unsigned long long)tv.tv_usec)/1000) : 0; (((unsigned long long)tv.tv_usec)/1000) : 0;
virEventInterruptLocked(); virEventPollInterruptLocked();
break; break;
} }
} }
...@@ -265,7 +265,7 @@ void virEventUpdateTimeoutImpl(int timer, int frequency) { ...@@ -265,7 +265,7 @@ void virEventUpdateTimeoutImpl(int timer, int frequency) {
* For this reason we only ever set a flag in the existing list. * For this reason we only ever set a flag in the existing list.
* Actual deletion will be done out-of-band * Actual deletion will be done out-of-band
*/ */
int virEventRemoveTimeoutImpl(int timer) { int virEventPollRemoveTimeout(int timer) {
int i; int i;
EVENT_DEBUG("Remove timer %d", timer); EVENT_DEBUG("Remove timer %d", timer);
...@@ -281,7 +281,7 @@ int virEventRemoveTimeoutImpl(int timer) { ...@@ -281,7 +281,7 @@ int virEventRemoveTimeoutImpl(int timer) {
if (eventLoop.timeouts[i].timer == timer) { if (eventLoop.timeouts[i].timer == timer) {
eventLoop.timeouts[i].deleted = 1; eventLoop.timeouts[i].deleted = 1;
virEventInterruptLocked(); virEventPollInterruptLocked();
virMutexUnlock(&eventLoop.lock); virMutexUnlock(&eventLoop.lock);
return 0; return 0;
} }
...@@ -296,7 +296,7 @@ int virEventRemoveTimeoutImpl(int timer) { ...@@ -296,7 +296,7 @@ int virEventRemoveTimeoutImpl(int timer) {
* no timeout is pending * no timeout is pending
* returns: 0 on success, -1 on error * returns: 0 on success, -1 on error
*/ */
static int virEventCalculateTimeout(int *timeout) { static int virEventPollCalculateTimeout(int *timeout) {
unsigned long long then = 0; unsigned long long then = 0;
int i; int i;
EVENT_DEBUG("Calculate expiry of %zu timers", eventLoop.timeoutsCount); EVENT_DEBUG("Calculate expiry of %zu timers", eventLoop.timeoutsCount);
...@@ -339,7 +339,7 @@ static int virEventCalculateTimeout(int *timeout) { ...@@ -339,7 +339,7 @@ static int virEventCalculateTimeout(int *timeout) {
* file handles. The caller must free the returned data struct * file handles. The caller must free the returned data struct
* returns: the pollfd array, or NULL on error * returns: the pollfd array, or NULL on error
*/ */
static struct pollfd *virEventMakePollFDs(int *nfds) { static struct pollfd *virEventPollMakePollFDs(int *nfds) {
struct pollfd *fds; struct pollfd *fds;
int i; int i;
...@@ -384,7 +384,7 @@ static struct pollfd *virEventMakePollFDs(int *nfds) { ...@@ -384,7 +384,7 @@ static struct pollfd *virEventMakePollFDs(int *nfds) {
* *
* Returns 0 upon success, -1 if an error occurred * Returns 0 upon success, -1 if an error occurred
*/ */
static int virEventDispatchTimeouts(void) { static int virEventPollDispatchTimeouts(void) {
struct timeval tv; struct timeval tv;
unsigned long long now; unsigned long long now;
int i; int i;
...@@ -433,7 +433,7 @@ static int virEventDispatchTimeouts(void) { ...@@ -433,7 +433,7 @@ static int virEventDispatchTimeouts(void) {
* *
* Returns 0 upon success, -1 if an error occurred * Returns 0 upon success, -1 if an error occurred
*/ */
static int virEventDispatchHandles(int nfds, struct pollfd *fds) { static int virEventPollDispatchHandles(int nfds, struct pollfd *fds) {
int i, n; int i, n;
VIR_DEBUG("Dispatch %d", nfds); VIR_DEBUG("Dispatch %d", nfds);
...@@ -460,7 +460,7 @@ static int virEventDispatchHandles(int nfds, struct pollfd *fds) { ...@@ -460,7 +460,7 @@ static int virEventDispatchHandles(int nfds, struct pollfd *fds) {
virEventHandleCallback cb = eventLoop.handles[i].cb; virEventHandleCallback cb = eventLoop.handles[i].cb;
int watch = eventLoop.handles[i].watch; int watch = eventLoop.handles[i].watch;
void *opaque = eventLoop.handles[i].opaque; void *opaque = eventLoop.handles[i].opaque;
int hEvents = virPollEventToEventHandleType(fds[n].revents); int hEvents = virEventPollFromNativeEvents(fds[n].revents);
EVENT_DEBUG("Dispatch n=%d f=%d w=%d e=%d %p", i, EVENT_DEBUG("Dispatch n=%d f=%d w=%d e=%d %p", i,
fds[n].fd, watch, fds[n].revents, opaque); fds[n].fd, watch, fds[n].revents, opaque);
virMutexUnlock(&eventLoop.lock); virMutexUnlock(&eventLoop.lock);
...@@ -477,7 +477,7 @@ static int virEventDispatchHandles(int nfds, struct pollfd *fds) { ...@@ -477,7 +477,7 @@ static int virEventDispatchHandles(int nfds, struct pollfd *fds) {
* were previously marked as deleted. This asynchronous * were previously marked as deleted. This asynchronous
* cleanup is needed to make dispatch re-entrant safe. * cleanup is needed to make dispatch re-entrant safe.
*/ */
static int virEventCleanupTimeouts(void) { static void virEventPollCleanupTimeouts(void) {
int i; int i;
size_t gap; size_t gap;
VIR_DEBUG("Cleanup %zu", eventLoop.timeoutsCount); VIR_DEBUG("Cleanup %zu", eventLoop.timeoutsCount);
...@@ -499,7 +499,7 @@ static int virEventCleanupTimeouts(void) { ...@@ -499,7 +499,7 @@ static int virEventCleanupTimeouts(void) {
if ((i+1) < eventLoop.timeoutsCount) { if ((i+1) < eventLoop.timeoutsCount) {
memmove(eventLoop.timeouts+i, memmove(eventLoop.timeouts+i,
eventLoop.timeouts+i+1, eventLoop.timeouts+i+1,
sizeof(struct virEventTimeout)*(eventLoop.timeoutsCount sizeof(struct virEventPollTimeout)*(eventLoop.timeoutsCount
-(i+1))); -(i+1)));
} }
eventLoop.timeoutsCount--; eventLoop.timeoutsCount--;
...@@ -513,14 +513,13 @@ static int virEventCleanupTimeouts(void) { ...@@ -513,14 +513,13 @@ static int virEventCleanupTimeouts(void) {
eventLoop.timeoutsCount, eventLoop.timeoutsAlloc, gap); eventLoop.timeoutsCount, eventLoop.timeoutsAlloc, gap);
VIR_SHRINK_N(eventLoop.timeouts, eventLoop.timeoutsAlloc, gap); VIR_SHRINK_N(eventLoop.timeouts, eventLoop.timeoutsAlloc, gap);
} }
return 0;
} }
/* Used post dispatch to actually remove any handles that /* Used post dispatch to actually remove any handles that
* were previously marked as deleted. This asynchronous * were previously marked as deleted. This asynchronous
* cleanup is needed to make dispatch re-entrant safe. * cleanup is needed to make dispatch re-entrant safe.
*/ */
static int virEventCleanupHandles(void) { static void virEventPollCleanupHandles(void) {
int i; int i;
size_t gap; size_t gap;
VIR_DEBUG("Cleanup %zu", eventLoop.handlesCount); VIR_DEBUG("Cleanup %zu", eventLoop.handlesCount);
...@@ -540,7 +539,7 @@ static int virEventCleanupHandles(void) { ...@@ -540,7 +539,7 @@ static int virEventCleanupHandles(void) {
if ((i+1) < eventLoop.handlesCount) { if ((i+1) < eventLoop.handlesCount) {
memmove(eventLoop.handles+i, memmove(eventLoop.handles+i,
eventLoop.handles+i+1, eventLoop.handles+i+1,
sizeof(struct virEventHandle)*(eventLoop.handlesCount sizeof(struct virEventPollHandle)*(eventLoop.handlesCount
-(i+1))); -(i+1)));
} }
eventLoop.handlesCount--; eventLoop.handlesCount--;
...@@ -554,14 +553,13 @@ static int virEventCleanupHandles(void) { ...@@ -554,14 +553,13 @@ static int virEventCleanupHandles(void) {
eventLoop.handlesCount, eventLoop.handlesAlloc, gap); eventLoop.handlesCount, eventLoop.handlesAlloc, gap);
VIR_SHRINK_N(eventLoop.handles, eventLoop.handlesAlloc, gap); VIR_SHRINK_N(eventLoop.handles, eventLoop.handlesAlloc, gap);
} }
return 0;
} }
/* /*
* Run a single iteration of the event loop, blocking until * Run a single iteration of the event loop, blocking until
* at least one file handle has an event, or a timer expires * at least one file handle has an event, or a timer expires
*/ */
int virEventRunOnce(void) { int virEventPollRunOnce(void) {
struct pollfd *fds = NULL; struct pollfd *fds = NULL;
int ret, timeout, nfds; int ret, timeout, nfds;
...@@ -569,12 +567,11 @@ int virEventRunOnce(void) { ...@@ -569,12 +567,11 @@ int virEventRunOnce(void) {
eventLoop.running = 1; eventLoop.running = 1;
virThreadSelf(&eventLoop.leader); virThreadSelf(&eventLoop.leader);
if (virEventCleanupTimeouts() < 0 || virEventPollCleanupTimeouts();
virEventCleanupHandles() < 0) virEventPollCleanupHandles();
goto error;
if (!(fds = virEventMakePollFDs(&nfds)) || if (!(fds = virEventPollMakePollFDs(&nfds)) ||
virEventCalculateTimeout(&timeout) < 0) virEventPollCalculateTimeout(&timeout) < 0)
goto error; goto error;
virMutexUnlock(&eventLoop.lock); virMutexUnlock(&eventLoop.lock);
...@@ -592,16 +589,15 @@ int virEventRunOnce(void) { ...@@ -592,16 +589,15 @@ int virEventRunOnce(void) {
EVENT_DEBUG("Poll got %d event(s)", ret); EVENT_DEBUG("Poll got %d event(s)", ret);
virMutexLock(&eventLoop.lock); virMutexLock(&eventLoop.lock);
if (virEventDispatchTimeouts() < 0) if (virEventPollDispatchTimeouts() < 0)
goto error; goto error;
if (ret > 0 && if (ret > 0 &&
virEventDispatchHandles(nfds, fds) < 0) virEventPollDispatchHandles(nfds, fds) < 0)
goto error; goto error;
if (virEventCleanupTimeouts() < 0 || virEventPollCleanupTimeouts();
virEventCleanupHandles() < 0) virEventPollCleanupHandles();
goto error;
eventLoop.running = 0; eventLoop.running = 0;
virMutexUnlock(&eventLoop.lock); virMutexUnlock(&eventLoop.lock);
...@@ -616,7 +612,7 @@ error_unlocked: ...@@ -616,7 +612,7 @@ error_unlocked:
} }
static void virEventHandleWakeup(int watch ATTRIBUTE_UNUSED, static void virEventPollHandleWakeup(int watch ATTRIBUTE_UNUSED,
int fd, int fd,
int events ATTRIBUTE_UNUSED, int events ATTRIBUTE_UNUSED,
void *opaque ATTRIBUTE_UNUSED) void *opaque ATTRIBUTE_UNUSED)
...@@ -627,27 +623,30 @@ static void virEventHandleWakeup(int watch ATTRIBUTE_UNUSED, ...@@ -627,27 +623,30 @@ static void virEventHandleWakeup(int watch ATTRIBUTE_UNUSED,
virMutexUnlock(&eventLoop.lock); virMutexUnlock(&eventLoop.lock);
} }
int virEventInit(void) int virEventPollInit(void)
{ {
if (virMutexInit(&eventLoop.lock) < 0) if (virMutexInit(&eventLoop.lock) < 0) {
return -1; return -1;
}
if (pipe(eventLoop.wakeupfd) < 0 || if (pipe(eventLoop.wakeupfd) < 0 ||
virSetNonBlock(eventLoop.wakeupfd[0]) < 0 || virSetNonBlock(eventLoop.wakeupfd[0]) < 0 ||
virSetNonBlock(eventLoop.wakeupfd[1]) < 0 || virSetNonBlock(eventLoop.wakeupfd[1]) < 0 ||
virSetCloseExec(eventLoop.wakeupfd[0]) < 0 || virSetCloseExec(eventLoop.wakeupfd[0]) < 0 ||
virSetCloseExec(eventLoop.wakeupfd[1]) < 0) virSetCloseExec(eventLoop.wakeupfd[1]) < 0) {
return -1; return -1;
}
if (virEventAddHandleImpl(eventLoop.wakeupfd[0], if (virEventPollAddHandle(eventLoop.wakeupfd[0],
VIR_EVENT_HANDLE_READABLE, VIR_EVENT_HANDLE_READABLE,
virEventHandleWakeup, NULL, NULL) < 0) virEventPollHandleWakeup, NULL, NULL) < 0) {
return -1; return -1;
}
return 0; return 0;
} }
static int virEventInterruptLocked(void) static int virEventPollInterruptLocked(void)
{ {
char c = '\0'; char c = '\0';
...@@ -664,17 +663,17 @@ static int virEventInterruptLocked(void) ...@@ -664,17 +663,17 @@ static int virEventInterruptLocked(void)
return 0; return 0;
} }
int virEventInterrupt(void) int virEventPollInterrupt(void)
{ {
int ret; int ret;
virMutexLock(&eventLoop.lock); virMutexLock(&eventLoop.lock);
ret = virEventInterruptLocked(); ret = virEventPollInterruptLocked();
virMutexUnlock(&eventLoop.lock); virMutexUnlock(&eventLoop.lock);
return ret; return ret;
} }
int int
virEventHandleTypeToPollEvent(int events) virEventPollToNativeEvents(int events)
{ {
int ret = 0; int ret = 0;
if(events & VIR_EVENT_HANDLE_READABLE) if(events & VIR_EVENT_HANDLE_READABLE)
...@@ -689,7 +688,7 @@ virEventHandleTypeToPollEvent(int events) ...@@ -689,7 +688,7 @@ virEventHandleTypeToPollEvent(int events)
} }
int int
virPollEventToEventHandleType(int events) virEventPollFromNativeEvents(int events)
{ {
int ret = 0; int ret = 0;
if(events & POLLIN) if(events & POLLIN)
......
...@@ -21,13 +21,13 @@ ...@@ -21,13 +21,13 @@
* Author: Daniel P. Berrange <berrange@redhat.com> * Author: Daniel P. Berrange <berrange@redhat.com>
*/ */
#ifndef __VIRTD_EVENT_H__ #ifndef __VIR_EVENT_POLL_H__
# define __VIRTD_EVENT_H__ # define __VIR_EVENT_POLL_H__
# include "internal.h" # include "internal.h"
/** /**
* virEventAddHandleImpl: register a callback for monitoring file handle events * virEventPollAddHandle: register a callback for monitoring file handle events
* *
* @fd: file handle to monitor for events * @fd: file handle to monitor for events
* @events: bitset of events to watch from POLLnnn constants * @events: bitset of events to watch from POLLnnn constants
...@@ -36,32 +36,32 @@ ...@@ -36,32 +36,32 @@
* *
* returns -1 if the file handle cannot be registered, 0 upon success * returns -1 if the file handle cannot be registered, 0 upon success
*/ */
int virEventAddHandleImpl(int fd, int events, int virEventPollAddHandle(int fd, int events,
virEventHandleCallback cb, virEventHandleCallback cb,
void *opaque, void *opaque,
virFreeCallback ff); virFreeCallback ff);
/** /**
* virEventUpdateHandleImpl: change event set for a monitored file handle * virEventPollUpdateHandle: change event set for a monitored file handle
* *
* @watch: watch whose handle to update * @watch: watch whose handle to update
* @events: bitset of events to watch from POLLnnn constants * @events: bitset of events to watch from POLLnnn constants
* *
* Will not fail if fd exists * Will not fail if fd exists
*/ */
void virEventUpdateHandleImpl(int watch, int events); void virEventPollUpdateHandle(int watch, int events);
/** /**
* virEventRemoveHandleImpl: unregister a callback from a file handle * virEventPollRemoveHandle: unregister a callback from a file handle
* *
* @watch: watch whose handle to remove * @watch: watch whose handle to remove
* *
* returns -1 if the file handle was not registered, 0 upon success * returns -1 if the file handle was not registered, 0 upon success
*/ */
int virEventRemoveHandleImpl(int watch); int virEventPollRemoveHandle(int watch);
/** /**
* virEventAddTimeoutImpl: register a callback for a timer event * virEventPollAddTimeout: register a callback for a timer event
* *
* @frequency: time between events in milliseconds * @frequency: time between events in milliseconds
* @cb: callback to invoke when an event occurs * @cb: callback to invoke when an event occurs
...@@ -73,13 +73,13 @@ int virEventRemoveHandleImpl(int watch); ...@@ -73,13 +73,13 @@ int virEventRemoveHandleImpl(int watch);
* returns -1 if the file handle cannot be registered, a positive * returns -1 if the file handle cannot be registered, a positive
* integer timer id upon success * integer timer id upon success
*/ */
int virEventAddTimeoutImpl(int frequency, int virEventPollAddTimeout(int frequency,
virEventTimeoutCallback cb, virEventTimeoutCallback cb,
void *opaque, void *opaque,
virFreeCallback ff); virFreeCallback ff);
/** /**
* virEventUpdateTimeoutImpl: change frequency for a timer * virEventPollUpdateTimeout: change frequency for a timer
* *
* @timer: timer id to change * @timer: timer id to change
* @frequency: time between events in milliseconds * @frequency: time between events in milliseconds
...@@ -89,46 +89,44 @@ int virEventAddTimeoutImpl(int frequency, ...@@ -89,46 +89,44 @@ int virEventAddTimeoutImpl(int frequency,
* *
* Will not fail if timer exists * Will not fail if timer exists
*/ */
void virEventUpdateTimeoutImpl(int timer, int frequency); void virEventPollUpdateTimeout(int timer, int frequency);
/** /**
* virEventRemoveTimeoutImpl: unregister a callback for a timer * virEventPollRemoveTimeout: unregister a callback for a timer
* *
* @timer: the timer id to remove * @timer: the timer id to remove
* *
* returns -1 if the timer was not registered, 0 upon success * returns -1 if the timer was not registered, 0 upon success
*/ */
int virEventRemoveTimeoutImpl(int timer); int virEventPollRemoveTimeout(int timer);
/** /**
* virEventInit: Initialize the event loop * virEventPollInit: Initialize the event loop
* *
* returns -1 if initialization failed * returns -1 if initialization failed
*/ */
int virEventInit(void); int virEventPollInit(void);
/** /**
* virEventRunOnce: run a single iteration of the event loop. * virEventPollRunOnce: run a single iteration of the event loop.
* *
* Blocks the caller until at least one file handle has an * Blocks the caller until at least one file handle has an
* event or the first timer expires. * event or the first timer expires.
* *
* returns -1 if the event monitoring failed * returns -1 if the event monitoring failed
*/ */
int virEventRunOnce(void); int virEventPollRunOnce(void);
int int virEventPollFromNativeEvents(int events);
virEventHandleTypeToPollEvent(int events); int virEventPollToNativeEvents(int events);
int
virPollEventToEventHandleType(int events);
/** /**
* virEventInterrupt: wakeup any thread waiting in poll() * virEventPollInterrupt: wakeup any thread waiting in poll()
* *
* return -1 if wakup failed * return -1 if wakup failed
*/ */
int virEventInterrupt(void); int virEventPollInterrupt(void);
#endif /* __VIRTD_EVENT_H__ */ #endif /* __VIRTD_EVENT_H__ */
...@@ -375,7 +375,7 @@ virbuftest_LDADD = $(LDADDS) ...@@ -375,7 +375,7 @@ virbuftest_LDADD = $(LDADDS)
if WITH_LIBVIRTD if WITH_LIBVIRTD
eventtest_SOURCES = \ eventtest_SOURCES = \
eventtest.c testutils.h testutils.c ../daemon/event.c eventtest.c testutils.h testutils.c
eventtest_LDADD = -lrt $(LDADDS) eventtest_LDADD = -lrt $(LDADDS)
endif endif
......
...@@ -31,7 +31,8 @@ ...@@ -31,7 +31,8 @@
#include "threads.h" #include "threads.h"
#include "logging.h" #include "logging.h"
#include "util.h" #include "util.h"
#include "../daemon/event.h" #include "event.h"
#include "event_poll.h"
#define NUM_FDS 31 #define NUM_FDS 31
#define NUM_TIME 31 #define NUM_TIME 31
...@@ -89,7 +90,7 @@ testPipeReader(int watch, int fd, int events, void *data) ...@@ -89,7 +90,7 @@ testPipeReader(int watch, int fd, int events, void *data)
info->error = EV_ERROR_NONE; info->error = EV_ERROR_NONE;
if (info->delete != -1) if (info->delete != -1)
virEventRemoveHandleImpl(info->delete); virEventPollRemoveHandle(info->delete);
} }
...@@ -108,7 +109,7 @@ testTimer(int timer, void *data) ...@@ -108,7 +109,7 @@ testTimer(int timer, void *data)
info->error = EV_ERROR_NONE; info->error = EV_ERROR_NONE;
if (info->delete != -1) if (info->delete != -1)
virEventRemoveTimeoutImpl(info->delete); virEventPollRemoveTimeout(info->delete);
} }
static pthread_mutex_t eventThreadMutex = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t eventThreadMutex = PTHREAD_MUTEX_INITIALIZER;
...@@ -127,7 +128,7 @@ static void *eventThreadLoop(void *data ATTRIBUTE_UNUSED) { ...@@ -127,7 +128,7 @@ static void *eventThreadLoop(void *data ATTRIBUTE_UNUSED) {
eventThreadRunOnce = 0; eventThreadRunOnce = 0;
pthread_mutex_unlock(&eventThreadMutex); pthread_mutex_unlock(&eventThreadMutex);
virEventRunOnce(); virEventPollRunOnce();
pthread_mutex_lock(&eventThreadMutex); pthread_mutex_lock(&eventThreadMutex);
eventThreadJobDone = 1; eventThreadJobDone = 1;
...@@ -288,12 +289,12 @@ mymain(int argc, char **argv) ...@@ -288,12 +289,12 @@ mymain(int argc, char **argv)
return EXIT_FAILURE; return EXIT_FAILURE;
} }
virEventInit(); virEventPollInit();
for (i = 0 ; i < NUM_FDS ; i++) { for (i = 0 ; i < NUM_FDS ; i++) {
handles[i].delete = -1; handles[i].delete = -1;
handles[i].watch = handles[i].watch =
virEventAddHandleImpl(handles[i].pipeFD[0], virEventPollAddHandle(handles[i].pipeFD[0],
VIR_EVENT_HANDLE_READABLE, VIR_EVENT_HANDLE_READABLE,
testPipeReader, testPipeReader,
&handles[i], NULL); &handles[i], NULL);
...@@ -303,7 +304,7 @@ mymain(int argc, char **argv) ...@@ -303,7 +304,7 @@ mymain(int argc, char **argv)
timers[i].delete = -1; timers[i].delete = -1;
timers[i].timeout = -1; timers[i].timeout = -1;
timers[i].timer = timers[i].timer =
virEventAddTimeoutImpl(timers[i].timeout, virEventPollAddTimeout(timers[i].timeout,
testTimer, testTimer,
&timers[i], NULL); &timers[i], NULL);
} }
...@@ -324,7 +325,7 @@ mymain(int argc, char **argv) ...@@ -324,7 +325,7 @@ mymain(int argc, char **argv)
/* Now lets delete one before starting poll(), and /* Now lets delete one before starting poll(), and
* try triggering another handle */ * try triggering another handle */
virEventRemoveHandleImpl(handles[0].watch); virEventPollRemoveHandle(handles[0].watch);
startJob(); startJob();
if (safewrite(handles[1].pipeFD[1], &one, 1) != 1) if (safewrite(handles[1].pipeFD[1], &one, 1) != 1)
return EXIT_FAILURE; return EXIT_FAILURE;
...@@ -338,13 +339,13 @@ mymain(int argc, char **argv) ...@@ -338,13 +339,13 @@ mymain(int argc, char **argv)
/* NB: this case is subject to a bit of a race condition. /* NB: this case is subject to a bit of a race condition.
* We yield & sleep, and pray that the other thread gets * We yield & sleep, and pray that the other thread gets
* scheduled before we run EventRemoveHandleImpl */ * scheduled before we run EventRemoveHandle */
startJob(); startJob();
pthread_mutex_unlock(&eventThreadMutex); pthread_mutex_unlock(&eventThreadMutex);
sched_yield(); sched_yield();
usleep(100 * 1000); usleep(100 * 1000);
pthread_mutex_lock(&eventThreadMutex); pthread_mutex_lock(&eventThreadMutex);
virEventRemoveHandleImpl(handles[1].watch); virEventPollRemoveHandle(handles[1].watch);
if (finishJob("Interrupted during poll", -1, -1) != EXIT_SUCCESS) if (finishJob("Interrupted during poll", -1, -1) != EXIT_SUCCESS)
return EXIT_FAILURE; return EXIT_FAILURE;
...@@ -380,22 +381,22 @@ mymain(int argc, char **argv) ...@@ -380,22 +381,22 @@ mymain(int argc, char **argv)
/* Run a timer on its own */ /* Run a timer on its own */
virEventUpdateTimeoutImpl(timers[1].timer, 100); virEventPollUpdateTimeout(timers[1].timer, 100);
startJob(); startJob();
if (finishJob("Firing a timer", -1, 1) != EXIT_SUCCESS) if (finishJob("Firing a timer", -1, 1) != EXIT_SUCCESS)
return EXIT_FAILURE; return EXIT_FAILURE;
virEventUpdateTimeoutImpl(timers[1].timer, -1); virEventPollUpdateTimeout(timers[1].timer, -1);
resetAll(); resetAll();
/* Now lets delete one before starting poll(), and /* Now lets delete one before starting poll(), and
* try triggering another timer */ * try triggering another timer */
virEventUpdateTimeoutImpl(timers[1].timer, 100); virEventPollUpdateTimeout(timers[1].timer, 100);
virEventRemoveTimeoutImpl(timers[0].timer); virEventPollRemoveTimeout(timers[0].timer);
startJob(); startJob();
if (finishJob("Deleted before poll", -1, 1) != EXIT_SUCCESS) if (finishJob("Deleted before poll", -1, 1) != EXIT_SUCCESS)
return EXIT_FAILURE; return EXIT_FAILURE;
virEventUpdateTimeoutImpl(timers[1].timer, -1); virEventPollUpdateTimeout(timers[1].timer, -1);
resetAll(); resetAll();
...@@ -404,13 +405,13 @@ mymain(int argc, char **argv) ...@@ -404,13 +405,13 @@ mymain(int argc, char **argv)
/* NB: this case is subject to a bit of a race condition. /* NB: this case is subject to a bit of a race condition.
* We yield & sleep, and pray that the other thread gets * We yield & sleep, and pray that the other thread gets
* scheduled before we run EventRemoveTimeoutImpl */ * scheduled before we run EventRemoveTimeout */
startJob(); startJob();
pthread_mutex_unlock(&eventThreadMutex); pthread_mutex_unlock(&eventThreadMutex);
sched_yield(); sched_yield();
usleep(100 * 1000); usleep(100 * 1000);
pthread_mutex_lock(&eventThreadMutex); pthread_mutex_lock(&eventThreadMutex);
virEventRemoveTimeoutImpl(timers[1].timer); virEventPollRemoveTimeout(timers[1].timer);
if (finishJob("Interrupted during poll", -1, -1) != EXIT_SUCCESS) if (finishJob("Interrupted during poll", -1, -1) != EXIT_SUCCESS)
return EXIT_FAILURE; return EXIT_FAILURE;
...@@ -423,27 +424,27 @@ mymain(int argc, char **argv) ...@@ -423,27 +424,27 @@ mymain(int argc, char **argv)
* before poll() exits for the first safewrite(). We don't * before poll() exits for the first safewrite(). We don't
* see a hard failure in other cases, so nothing to worry * see a hard failure in other cases, so nothing to worry
* about */ * about */
virEventUpdateTimeoutImpl(timers[2].timer, 100); virEventPollUpdateTimeout(timers[2].timer, 100);
virEventUpdateTimeoutImpl(timers[3].timer, 100); virEventPollUpdateTimeout(timers[3].timer, 100);
startJob(); startJob();
timers[2].delete = timers[3].timer; timers[2].delete = timers[3].timer;
if (finishJob("Deleted during dispatch", -1, 2) != EXIT_SUCCESS) if (finishJob("Deleted during dispatch", -1, 2) != EXIT_SUCCESS)
return EXIT_FAILURE; return EXIT_FAILURE;
virEventUpdateTimeoutImpl(timers[2].timer, -1); virEventPollUpdateTimeout(timers[2].timer, -1);
resetAll(); resetAll();
/* Extreme fun, lets delete ourselves during dispatch */ /* Extreme fun, lets delete ourselves during dispatch */
virEventUpdateTimeoutImpl(timers[2].timer, 100); virEventPollUpdateTimeout(timers[2].timer, 100);
startJob(); startJob();
timers[2].delete = timers[2].timer; timers[2].delete = timers[2].timer;
if (finishJob("Deleted during dispatch", -1, 2) != EXIT_SUCCESS) if (finishJob("Deleted during dispatch", -1, 2) != EXIT_SUCCESS)
return EXIT_FAILURE; return EXIT_FAILURE;
for (i = 0 ; i < NUM_FDS - 1 ; i++) for (i = 0 ; i < NUM_FDS - 1 ; i++)
virEventRemoveHandleImpl(handles[i].watch); virEventPollRemoveHandle(handles[i].watch);
for (i = 0 ; i < NUM_TIME - 1 ; i++) for (i = 0 ; i < NUM_TIME - 1 ; i++)
virEventRemoveTimeoutImpl(timers[i].timer); virEventPollRemoveTimeout(timers[i].timer);
resetAll(); resetAll();
...@@ -464,11 +465,11 @@ mymain(int argc, char **argv) ...@@ -464,11 +465,11 @@ mymain(int argc, char **argv)
handles[0].pipeFD[0] = handles[1].pipeFD[0]; handles[0].pipeFD[0] = handles[1].pipeFD[0];
handles[0].pipeFD[1] = handles[1].pipeFD[1]; handles[0].pipeFD[1] = handles[1].pipeFD[1];
handles[0].watch = virEventAddHandleImpl(handles[0].pipeFD[0], handles[0].watch = virEventPollAddHandle(handles[0].pipeFD[0],
0, 0,
testPipeReader, testPipeReader,
&handles[0], NULL); &handles[0], NULL);
handles[1].watch = virEventAddHandleImpl(handles[1].pipeFD[0], handles[1].watch = virEventPollAddHandle(handles[1].pipeFD[0],
VIR_EVENT_HANDLE_READABLE, VIR_EVENT_HANDLE_READABLE,
testPipeReader, testPipeReader,
&handles[1], NULL); &handles[1], NULL);
......
...@@ -38,7 +38,6 @@ virt-pki-validate.1: virt-pki-validate.in ...@@ -38,7 +38,6 @@ virt-pki-validate.1: virt-pki-validate.in
virsh_SOURCES = \ virsh_SOURCES = \
console.c console.h \ console.c console.h \
../daemon/event.c ../daemon/event.h \
virsh.c virsh.c
virsh_LDFLAGS = $(WARN_LDFLAGS) $(COVERAGE_LDFLAGS) virsh_LDFLAGS = $(WARN_LDFLAGS) $(COVERAGE_LDFLAGS)
......
...@@ -43,8 +43,8 @@ ...@@ -43,8 +43,8 @@
# include "memory.h" # include "memory.h"
# include "virterror_internal.h" # include "virterror_internal.h"
# include "daemon/event.h" # include "event.h"
# include "src/util/event.h" # include "event_poll.h"
/* ie Ctrl-] as per telnet */ /* ie Ctrl-] as per telnet */
# define CTRL_CLOSE_BRACKET '\35' # define CTRL_CLOSE_BRACKET '\35'
...@@ -350,7 +350,7 @@ int vshRunConsole(virDomainPtr dom, const char *devname) ...@@ -350,7 +350,7 @@ int vshRunConsole(virDomainPtr dom, const char *devname)
NULL); NULL);
while (!con->quit) { while (!con->quit) {
if (virEventRunOnce() < 0) if (virEventPollRunOnce() < 0)
break; break;
} }
......
...@@ -53,7 +53,7 @@ ...@@ -53,7 +53,7 @@
#include "xml.h" #include "xml.h"
#include "libvirt/libvirt-qemu.h" #include "libvirt/libvirt-qemu.h"
#include "files.h" #include "files.h"
#include "../daemon/event.h" #include "event_poll.h"
#include "configmake.h" #include "configmake.h"
#include "threads.h" #include "threads.h"
#include "command.h" #include "command.h"
...@@ -11677,13 +11677,13 @@ vshInit(vshControl *ctl) ...@@ -11677,13 +11677,13 @@ vshInit(vshControl *ctl)
/* set up the signals handlers to catch disconnections */ /* set up the signals handlers to catch disconnections */
vshSetupSignals(); vshSetupSignals();
virEventRegisterImpl(virEventAddHandleImpl, virEventRegisterImpl(virEventPollAddHandle,
virEventUpdateHandleImpl, virEventPollUpdateHandle,
virEventRemoveHandleImpl, virEventPollRemoveHandle,
virEventAddTimeoutImpl, virEventPollAddTimeout,
virEventUpdateTimeoutImpl, virEventPollUpdateTimeout,
virEventRemoveTimeoutImpl); virEventPollRemoveTimeout);
virEventInit(); virEventPollInit();
ctl->conn = virConnectOpenAuth(ctl->name, ctl->conn = virConnectOpenAuth(ctl->name,
virConnectAuthPtrDefault, virConnectAuthPtrDefault,
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册