[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