[libvirt] [PATCH v3 04/13] virsh: Always run event loop
Daniel P. Berrange
berrange at redhat.com
Tue Oct 18 09:31:54 UTC 2011
On Wed, Oct 12, 2011 at 07:16:22AM +0200, Jiri Denemark wrote:
> Since virsh already implements event loop, it has to also run it. So far
> the event loop was only running during virsh console command.
> ---
> Notes:
> Version 3:
> - new patch
>
> tools/console.c | 17 ++++++++++++++---
> tools/virsh.c | 31 +++++++++++++++++++++++++++++++
> 2 files changed, 45 insertions(+), 3 deletions(-)
>
> diff --git a/tools/console.c b/tools/console.c
> index 0f85bc7..e9e01a4 100644
> --- a/tools/console.c
> +++ b/tools/console.c
> @@ -41,6 +41,7 @@
> # include "util.h"
> # include "virfile.h"
> # include "memory.h"
> +# include "threads.h"
> # include "virterror_internal.h"
>
>
> @@ -60,6 +61,8 @@ typedef virConsole *virConsolePtr;
> struct virConsole {
> virStreamPtr st;
> bool quit;
> + virMutex lock;
> + virCond cond;
>
> int stdinWatch;
> int stdoutWatch;
> @@ -89,7 +92,6 @@ cfmakeraw (struct termios *attr)
> static void
> virConsoleShutdown(virConsolePtr con)
> {
> - con->quit = true;
> if (con->st) {
> virStreamEventRemoveCallback(con->st);
> virStreamAbort(con->st);
> @@ -101,6 +103,8 @@ virConsoleShutdown(virConsolePtr con)
> virEventRemoveHandle(con->stdoutWatch);
> con->stdinWatch = -1;
> con->stdoutWatch = -1;
> + con->quit = true;
> + virCondSignal(&con->cond);
> }
>
> static void
> @@ -334,6 +338,9 @@ int vshRunConsole(virDomainPtr dom, const char *dev_name)
> if (virDomainOpenConsole(dom, dev_name, con->st, 0) < 0)
> goto cleanup;
>
> + if (virCondInit(&con->cond) < 0 || virMutexInit(&con->lock) < 0)
> + goto cleanup;
> +
> con->stdinWatch = virEventAddHandle(STDIN_FILENO,
> VIR_EVENT_HANDLE_READABLE,
> virConsoleEventOnStdin,
> @@ -352,8 +359,10 @@ int vshRunConsole(virDomainPtr dom, const char *dev_name)
> NULL);
>
> while (!con->quit) {
> - if (virEventRunDefaultImpl() < 0)
> - break;
> + if (virCondWait(&con->cond, &con->lock) < 0) {
> + VIR_ERROR(_("unable to wait on console condition"));
> + goto cleanup;
> + }
> }
>
> ret = 0;
> @@ -363,6 +372,8 @@ int vshRunConsole(virDomainPtr dom, const char *dev_name)
> if (con) {
> if (con->st)
> virStreamFree(con->st);
> + virMutexDestroy(&con->lock);
> + ignore_value(virCondDestroy(&con->cond));
> VIR_FREE(con);
> }
>
> diff --git a/tools/virsh.c b/tools/virsh.c
> index bcf0603..1434697 100644
> --- a/tools/virsh.c
> +++ b/tools/virsh.c
> @@ -248,6 +248,9 @@ typedef struct __vshControl {
> virDomainGetState is not supported */
> bool useSnapshotOld; /* cannot use virDomainSnapshotGetParent or
> virDomainSnapshotNumChildren */
> + virThread eventLoop;
> + bool eventLoopStarted;
> + bool quit;
> } __vshControl;
>
> typedef struct vshCmdGrp {
> @@ -15843,6 +15846,19 @@ vshError(vshControl *ctl, const char *format, ...)
> }
>
>
> +static void
> +vshEventLoop(void *opaque)
> +{
> + vshControl *ctl = opaque;
> +
> + while (!ctl->quit) {
> + if (virEventRunDefaultImpl() < 0) {
> + virshReportError(ctl);
> + }
> + }
> +}
> +
> +
> /*
> * Initialize connection.
> */
> @@ -15888,6 +15904,10 @@ vshInit(vshControl *ctl)
> if (virEventRegisterDefaultImpl() < 0)
> return false;
>
> + if (virThreadCreate(&ctl->eventLoop, true, vshEventLoop, ctl) < 0)
> + return false;
> + ctl->eventLoopStarted = true;
> +
> if (ctl->name) {
> ctl->conn = virConnectOpenAuth(ctl->name,
> virConnectAuthPtrDefault,
> @@ -16276,6 +16296,7 @@ vshReadline (vshControl *ctl, const char *prompt)
> static bool
> vshDeinit(vshControl *ctl)
> {
> + ctl->quit = true;
> vshReadlineDeinit(ctl);
> vshCloseLogFile(ctl);
> VIR_FREE(ctl->name);
> @@ -16287,6 +16308,16 @@ vshDeinit(vshControl *ctl)
> }
> virResetLastError();
>
> + if (ctl->eventLoopStarted) {
> + /* HACK: Add a dummy timeout to break event loop */
> + int timer = virEventAddTimeout(-1, NULL, NULL, NULL);
> + if (timer != -1)
> + virEventRemoveTimeout(timer);
> +
> + virThreadJoin(&ctl->eventLoop);
> + ctl->eventLoopStarted = false;
> + }
> +
> return true;
> }
>
ACK, easier than I thought it would be
Daniel
--
|: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org -o- http://virt-manager.org :|
|: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|
More information about the libvir-list
mailing list