#include <string.h>
#include <signal.h>
-#if HAVE_SYS_POLL_H
-# include <sys/types.h>
-# include <sys/poll.h>
-# include <libvirt/libvirt.h>
+#include <libvirt/libvirt.h>
+#include <libvirt/virterror.h>
-# define VIR_DEBUG0(fmt) printf("%s:%d :: " fmt "\n", \
+#define VIR_DEBUG0(fmt) printf("%s:%d :: " fmt "\n", \
__func__, __LINE__)
-# define VIR_DEBUG(fmt, ...) printf("%s:%d: " fmt "\n", \
+#define VIR_DEBUG(fmt, ...) printf("%s:%d: " fmt "\n", \
__func__, __LINE__, __VA_ARGS__)
-# define STREQ(a,b) (strcmp(a,b) == 0)
-
-# ifndef ATTRIBUTE_UNUSED
-# define ATTRIBUTE_UNUSED __attribute__((__unused__))
-# endif
-
-/* handle globals */
-int h_fd = 0;
-virEventHandleType h_event = 0;
-virEventHandleCallback h_cb = NULL;
-virFreeCallback h_ff = NULL;
-void *h_opaque = NULL;
-
-/* timeout globals */
-# define TIMEOUT_MS 1000
-int t_active = 0;
-int t_timeout = -1;
-virEventTimeoutCallback t_cb = NULL;
-virFreeCallback t_ff = NULL;
-void *t_opaque = NULL;
+#define STREQ(a,b) (strcmp(a,b) == 0)
+#ifndef ATTRIBUTE_UNUSED
+# define ATTRIBUTE_UNUSED __attribute__((__unused__))
+#endif
/* Prototypes */
const char *eventToString(int event);
}
-/* EventImpl Functions */
-int myEventHandleTypeToPollEvent(virEventHandleType events)
-{
- int ret = 0;
- if(events & VIR_EVENT_HANDLE_READABLE)
- ret |= POLLIN;
- if(events & VIR_EVENT_HANDLE_WRITABLE)
- ret |= POLLOUT;
- if(events & VIR_EVENT_HANDLE_ERROR)
- ret |= POLLERR;
- if(events & VIR_EVENT_HANDLE_HANGUP)
- ret |= POLLHUP;
- return ret;
-}
-
-virEventHandleType myPollEventToEventHandleType(int events)
-{
- virEventHandleType ret = 0;
- if(events & POLLIN)
- ret |= VIR_EVENT_HANDLE_READABLE;
- if(events & POLLOUT)
- ret |= VIR_EVENT_HANDLE_WRITABLE;
- if(events & POLLERR)
- ret |= VIR_EVENT_HANDLE_ERROR;
- if(events & POLLHUP)
- ret |= VIR_EVENT_HANDLE_HANGUP;
- return ret;
-}
-
-int myEventAddHandleFunc(int fd, int event,
- virEventHandleCallback cb,
- void *opaque,
- virFreeCallback ff)
-{
- VIR_DEBUG("Add handle %d %d %p %p", fd, event, cb, opaque);
- h_fd = fd;
- h_event = myEventHandleTypeToPollEvent(event);
- h_cb = cb;
- h_ff = ff;
- h_opaque = opaque;
- return 0;
-}
-
-void myEventUpdateHandleFunc(int fd, int event)
-{
- VIR_DEBUG("Updated Handle %d %d", fd, event);
- h_event = myEventHandleTypeToPollEvent(event);
- return;
-}
-
-int myEventRemoveHandleFunc(int fd)
-{
- VIR_DEBUG("Removed Handle %d", fd);
- h_fd = 0;
- if (h_ff)
- (h_ff)(h_opaque);
- return 0;
-}
-
-int myEventAddTimeoutFunc(int timeout,
- virEventTimeoutCallback cb,
- void *opaque,
- virFreeCallback ff)
-{
- VIR_DEBUG("Adding Timeout %d %p %p", timeout, cb, opaque);
- t_active = 1;
- t_timeout = timeout;
- t_cb = cb;
- t_ff = ff;
- t_opaque = opaque;
- return 0;
-}
-
-void myEventUpdateTimeoutFunc(int timer ATTRIBUTE_UNUSED, int timeout)
-{
- /*VIR_DEBUG("Timeout updated %d %d", timer, timeout);*/
- t_timeout = timeout;
-}
-
-int myEventRemoveTimeoutFunc(int timer)
-{
- VIR_DEBUG("Timeout removed %d", timer);
- t_active = 0;
- if (t_ff)
- (t_ff)(t_opaque);
- return 0;
-}
-
/* main test functions */
void usage(const char *pname)
int main(int argc, char **argv)
{
- int sts;
int callback1ret = -1;
int callback2ret = -1;
int callback3ret = -1;
action_stop.sa_handler = stop;
- if(argc > 1 && STREQ(argv[1],"--help")) {
+ if (argc > 1 && STREQ(argv[1], "--help")) {
usage(argv[0]);
return -1;
}
- virEventRegisterImpl( myEventAddHandleFunc,
- myEventUpdateHandleFunc,
- myEventRemoveHandleFunc,
- myEventAddTimeoutFunc,
- myEventUpdateTimeoutFunc,
- myEventRemoveTimeoutFunc);
+ virEventRegisterDefaultImpl();
virConnectPtr dconn = NULL;
dconn = virConnectOpenReadOnly (argv[1] ? argv[1] : NULL);
(callback5ret != -1) &&
(callback6ret != -1) &&
(callback7ret != -1)) {
- while(run) {
- struct pollfd pfd = { .fd = h_fd,
- .events = h_event,
- .revents = 0};
-
- sts = poll(&pfd, 1, TIMEOUT_MS);
-
- /* if t_timeout < 0 then t_cb must not be called */
- if (t_cb && t_active && t_timeout >= 0) {
- t_cb(t_timeout,t_opaque);
- }
-
- if (sts == 0) {
- /* VIR_DEBUG0("Poll timeout"); */
- continue;
- }
- if (sts < 0 ) {
- VIR_DEBUG0("Poll failed");
- continue;
- }
- if ( pfd.revents & POLLHUP ) {
- VIR_DEBUG0("Reset by peer");
- return -1;
+ while (run) {
+ if (virEventRunDefaultImpl() < 0) {
+ virErrorPtr err = virGetLastError();
+ fprintf(stderr, "Failed to run event loop: %s\n",
+ err && err->message ? err->message : "Unknown error");
}
-
- if(h_cb) {
- h_cb(0,
- h_fd,
- myPollEventToEventHandleType(pfd.revents & h_event),
- h_opaque);
- }
-
}
VIR_DEBUG0("Deregistering event handlers");
}
VIR_DEBUG0("Closing connection");
- if( dconn && virConnectClose(dconn)<0 ) {
+ if (dconn && virConnectClose(dconn) < 0) {
printf("error closing\n");
}
printf("done\n");
return 0;
}
-
-#else
-int main(void) {
- printf("event-test program not available without sys/poll.h support\n");
- return 1;
-}
-#endif
import time
import threading
+# For the sake of demonstration, this example program includes
+# an implementation of a pure python event loop. Most applications
+# would be better off just using the default libvirt event loop
+# APIs, instead of implementing this in python. The exception is
+# where an application wants to integrate with an existing 3rd
+# party event loop impl
+#
+# Change this to 'False' to make the demo use the native
+# libvirt event loop impl
+use_pure_python_event_loop = True
+
do_debug = False
def debug(msg):
global do_debug
global eventLoop
eventLoop.run_loop()
+def virEventLoopNativeRun():
+ while True:
+ libvirt.virEventRunDefaultImpl()
+
# Spawn a background thread to run the event loop
def virEventLoopPureStart():
global eventLoopThread
eventLoopThread.setDaemon(True)
eventLoopThread.start()
+def virEventLoopNativeStart():
+ global eventLoopThread
+ libvirt.virEventRegisterDefaultImpl()
+ eventLoopThread = threading.Thread(target=virEventLoopNativeRun, name="libvirtEventLoop")
+ eventLoopThread.setDaemon(True)
+ eventLoopThread.start()
+
##########################################################################
# Everything that now follows is a simple demo of domain lifecycle events
print "Using uri:" + uri
# Run a background thread with the event loop
- virEventLoopPureStart()
+ if use_pure_python_event_loop:
+ virEventLoopPureStart()
+ else:
+ virEventLoopNativeStart()
- vc = libvirt.open(uri)
+ vc = libvirt.openReadOnly(uri)
# Close connection on exit (to test cleanup paths)
old_exitfunc = getattr(sys, 'exitfunc', None)