Exemple #1
1
/**
 * virEventRegisterDefaultImpl:
 *
 * Registers a default event implementation based on the
 * poll() system call. This is a generic implementation
 * that can be used by any client application which does
 * not have a need to integrate with an external event
 * loop impl.
 *
 * Once registered, the application can invoke
 * virEventRunDefaultImpl in a loop to process
 * events
 *
 * Returns 0 on success, -1 on failure.
 */
int virEventRegisterDefaultImpl(void)
{
    VIR_DEBUG("registering default event implementation");

    virResetLastError();

    if (virEventPollInit() < 0) {
        virDispatchError(NULL);
        return -1;
    }

    virEventRegisterImpl(
        virEventPollAddHandle,
        virEventPollUpdateHandle,
        virEventPollRemoveHandle,
        virEventPollAddTimeout,
        virEventPollUpdateTimeout,
        virEventPollRemoveTimeout
        );

    return 0;
}
Exemple #2
0
static void *
event_thread(void *arg)
{
	struct event_args *args = (struct event_args *)arg;
	virConnectPtr dconn = NULL;
	int callback1ret = -1;
	int sts;

	dbg_printf(3, "Libvirt event listener starting\n");
	if (args->uri)
		dbg_printf(3," * URI: %s\n", args->uri);
	if (args->path)
		dbg_printf(3," * Socket path: %s\n", args->path);
	dbg_printf(3," * Mode: %s\n", args->mode ? "VMChannel" : "Serial");

top:
	virEventRegisterImpl(myEventAddHandleFunc,
			     myEventUpdateHandleFunc,
			     myEventRemoveHandleFunc,
			     myEventAddTimeoutFunc,
			     myEventUpdateTimeoutFunc,
			     myEventRemoveTimeoutFunc);

	dconn = virConnectOpen(args->uri);
	if (!dconn) {
		dbg_printf(1, "Error connecting to libvirt\n");
		goto out;
	}

	DEBUG0("Registering domain event cbs");

	registerExisting(dconn, args->path, args->mode);

	callback1ret =
	    virConnectDomainEventRegister(dconn, myDomainEventCallback1, arg, NULL);

	if (callback1ret == 0) {
		while (run) {
			struct pollfd pfd = {
				.fd = h_fd,
				.events = h_event,
				.revents = 0
			};

			sts = poll(&pfd, 1, TIMEOUT_MS);
			/* We are assuming timeout of 0 here - so execute every time */
			if (t_cb && t_active) {
				t_cb(t_timeout, t_opaque);
			}

			if (sts == 0) {
				/* DEBUG0("Poll timeout"); */
				continue;
			}

			if (sts < 0) {
				DEBUG0("Poll failed");
				continue;
			}

			if (pfd.revents & POLLHUP) {
				DEBUG0("Reset by peer");
				virConnectDomainEventDeregister(dconn, myDomainEventCallback1);
				if (dconn && virConnectClose(dconn) < 0)
					dbg_printf(1, "error closing libvirt connection\n");
				DEBUG0("Attempting to reinitialize libvirt connection");
				goto top;
			}

			if (h_cb) {
				h_cb(0, h_fd,
				     myPollEventToEventHandleType(pfd.revents & h_event),
				     h_opaque);
			}
		}

		DEBUG0("Deregistering event handlers");
		virConnectDomainEventDeregister(dconn, myDomainEventCallback1);
	}

	DEBUG0("Closing connection");
	if (dconn && virConnectClose(dconn) < 0) {
		dbg_printf(1, "error closing libvirt connection\n");
	}

out:
	free(args->uri);
	free(args->path);
	free(args);
	return NULL;
}


int
start_event_listener(const char *uri, const char *path, int mode, int *wake_fd)
{
	struct event_args *args = NULL;
	int wake_pipe[2];

	virInitialize();

	args = malloc(sizeof(*args));
	if (!args)
		return -1;
	memset(args, 0, sizeof(*args));
       
	if (pipe2(wake_pipe, O_CLOEXEC) < 0) {
		goto out_fail;
	}

	if (uri) {
	       args->uri = strdup(uri);
	       if (args->uri == NULL)
		       goto out_fail;
	}

	if (path) {
	       args->path = strdup(path);
	       if (args->path == NULL)
		       goto out_fail;
	}

	args->mode = mode;
	//args->p_tid = pthread_self();
	*wake_fd = wake_pipe[0];
	args->wake_fd = wake_pipe[1];

	run = 1;

	return pthread_create(&event_tid, NULL, event_thread, args);

out_fail:
	free(args->uri);
	free(args->path);
	free(args);
	return -1;
}


int
stop_event_listener(void)
{
	run = 0;
	//pthread_cancel(event_tid);
	pthread_join(event_tid, NULL);
	event_tid = 0;

	return 0;
}