virsh: Always run event loop

Since virsh already implements event loop, it has to also run it. So far
the event loop was only running during virsh console command.
This commit is contained in:
Jiri Denemark 2011-10-11 15:05:52 +02:00
parent 8d6e3edd0e
commit fd7e85ac6a
2 changed files with 45 additions and 3 deletions

View File

@ -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);
}

View File

@ -250,6 +250,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 {
@ -16636,6 +16639,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.
*/
@ -16681,6 +16697,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,
@ -17069,6 +17089,7 @@ vshReadline (vshControl *ctl, const char *prompt)
static bool
vshDeinit(vshControl *ctl)
{
ctl->quit = true;
vshReadlineDeinit(ctl);
vshCloseLogFile(ctl);
VIR_FREE(ctl->name);
@ -17080,6 +17101,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;
}