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 :| -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list