#include "json.h"
#include "virfile.h"
#include "virtime.h"
+#include "virobject.h"
#define VIR_FROM_THIS VIR_FROM_QEMU
struct _qemuAgent {
+ virObject object;
+
virMutex lock; /* also used to protect fd */
virCond notify;
- int refs;
-
int fd;
int watch;
qemuAgentEvent await_event;
};
+static virClassPtr qemuAgentClass;
+static void qemuAgentDispose(void *obj);
+
+static int qemuAgentOnceInit(void)
+{
+ if (!(qemuAgentClass = virClassNew("qemuAgent",
+ sizeof(qemuAgent),
+ qemuAgentDispose)))
+ return -1;
+
+ return 0;
+}
+
+VIR_ONCE_GLOBAL_INIT(qemuAgent)
+
+
#if DEBUG_RAW_IO
# include <c-ctype.h>
static char *
}
-static void qemuAgentFree(qemuAgentPtr mon)
+static void qemuAgentDispose(void *obj)
{
+ qemuAgentPtr mon = obj;
VIR_DEBUG("mon=%p", mon);
if (mon->cb && mon->cb->destroy)
(mon->cb->destroy)(mon, mon->vm);
ignore_value(virCondDestroy(&mon->notify));
virMutexDestroy(&mon->lock);
VIR_FREE(mon->buffer);
- VIR_FREE(mon);
-}
-
-int qemuAgentRef(qemuAgentPtr mon)
-{
- mon->refs++;
- VIR_DEBUG("%d", mon->refs);
- return mon->refs;
-}
-
-int qemuAgentUnref(qemuAgentPtr mon)
-{
- mon->refs--;
- VIR_DEBUG("%d", mon->refs);
- if (mon->refs == 0) {
- qemuAgentUnlock(mon);
- qemuAgentFree(mon);
- return 0;
- }
-
- return mon->refs;
-}
-
-static void
-qemuAgentUnwatch(void *monitor)
-{
- qemuAgentPtr mon = monitor;
-
- qemuAgentLock(mon);
- if (qemuAgentUnref(mon) > 0)
- qemuAgentUnlock(mon);
}
static int
bool error = false;
bool eof = false;
+ virObjectRef(mon);
/* lock access to the monitor and protect fd */
qemuAgentLock(mon);
- qemuAgentRef(mon);
#if DEBUG_IO
VIR_DEBUG("Agent %p I/O on watch %d fd %d events %d", mon, watch, fd, events);
#endif
/* Make sure anyone waiting wakes up now */
virCondSignal(&mon->notify);
- if (qemuAgentUnref(mon) > 0)
- qemuAgentUnlock(mon);
+ qemuAgentUnlock(mon);
+ virObjectUnref(mon);
VIR_DEBUG("Triggering EOF callback");
(eofNotify)(mon, vm);
} else if (error) {
/* Make sure anyone waiting wakes up now */
virCondSignal(&mon->notify);
- if (qemuAgentUnref(mon) > 0)
- qemuAgentUnlock(mon);
+ qemuAgentUnlock(mon);
+ virObjectUnref(mon);
VIR_DEBUG("Triggering error callback");
(errorNotify)(mon, vm);
} else {
- if (qemuAgentUnref(mon) > 0)
- qemuAgentUnlock(mon);
+ qemuAgentUnlock(mon);
+ virObjectUnref(mon);
}
}
return NULL;
}
- if (VIR_ALLOC(mon) < 0) {
- virReportOOMError();
+ if (qemuAgentInitialize() < 0)
+ return NULL;
+
+ if (!(mon = virObjectNew(qemuAgentClass)))
return NULL;
- }
if (virMutexInit(&mon->lock) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
return NULL;
}
mon->fd = -1;
- mon->refs = 1;
mon->vm = vm;
mon->cb = cb;
qemuAgentLock(mon);
VIR_EVENT_HANDLE_WRITABLE :
0),
qemuAgentIO,
- mon, qemuAgentUnwatch)) < 0) {
+ mon,
+ virObjectFreeCallback)) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("unable to register monitor events"));
goto cleanup;
}
- qemuAgentRef(mon);
+ virObjectRef(mon);
VIR_DEBUG("New mon %p fd =%d watch=%d", mon, mon->fd, mon->watch);
qemuAgentUnlock(mon);
mon->msg->finished = 1;
virCondSignal(&mon->notify);
}
+ qemuAgentUnlock(mon);
- if (qemuAgentUnref(mon) > 0)
- qemuAgentUnlock(mon);
+ virObjectUnref(mon);
}
#define QEMU_AGENT_WAIT_TIME (1000ull * 5)
}
qemuMonitorLock(priv->mon);
- qemuMonitorRef(priv->mon);
+ virObjectRef(priv->mon);
ignore_value(virTimeMillisNow(&priv->monStart));
virDomainObjUnlock(obj);
if (driver_locked)
virDomainObjPtr obj)
{
qemuDomainObjPrivatePtr priv = obj->privateData;
- int refs;
+ bool hasRefs;
- refs = qemuMonitorUnref(priv->mon);
+ hasRefs = virObjectUnref(priv->mon);
- if (refs > 0)
+ if (hasRefs)
qemuMonitorUnlock(priv->mon);
if (driver_locked)
virDomainObjLock(obj);
priv->monStart = 0;
- if (refs == 0) {
+ if (!hasRefs)
priv->mon = NULL;
- }
if (priv->job.active == QEMU_JOB_ASYNC_NESTED) {
qemuDomainObjResetJob(priv);
qemuDomainObjPrivatePtr priv = obj->privateData;
qemuAgentLock(priv->agent);
- qemuAgentRef(priv->agent);
+ virObjectRef(priv->agent);
ignore_value(virTimeMillisNow(&priv->agentStart));
virDomainObjUnlock(obj);
if (driver_locked)
virDomainObjPtr obj)
{
qemuDomainObjPrivatePtr priv = obj->privateData;
- int refs;
+ bool hasRefs;
- refs = qemuAgentUnref(priv->agent);
+ hasRefs = virObjectUnref(priv->agent);
- if (refs > 0)
+ if (hasRefs)
qemuAgentUnlock(priv->agent);
if (driver_locked)
virDomainObjLock(obj);
priv->agentStart = 0;
- if (refs == 0) {
+ if (!hasRefs)
priv->agent = NULL;
- }
}
/*
#include "memory.h"
#include "logging.h"
#include "virfile.h"
+#include "virobject.h"
#ifdef WITH_DTRACE_PROBES
# include "libvirt_qemu_probes.h"
#define DEBUG_RAW_IO 0
struct _qemuMonitor {
+ virObject object;
+
virMutex lock; /* also used to protect fd */
virCond notify;
- int refs;
-
int fd;
int watch;
int hasSendFD;
unsigned json_hmp: 1;
};
+static virClassPtr qemuMonitorClass;
+static void qemuMonitorDispose(void *obj);
+
+static int qemuMonitorOnceInit(void)
+{
+ if (!(qemuMonitorClass = virClassNew("qemuMonitor",
+ sizeof(qemuMonitor),
+ qemuMonitorDispose)))
+ return -1;
+
+ return 0;
+}
+
+VIR_ONCE_GLOBAL_INIT(qemuMonitor)
+
VIR_ENUM_IMPL(qemuMonitorMigrationStatus,
QEMU_MONITOR_MIGRATION_STATUS_LAST,
}
-static void qemuMonitorFree(qemuMonitorPtr mon)
+static void qemuMonitorDispose(void *obj)
{
+ qemuMonitorPtr mon = obj;
+
VIR_DEBUG("mon=%p", mon);
if (mon->cb && mon->cb->destroy)
(mon->cb->destroy)(mon, mon->vm);
{}
virMutexDestroy(&mon->lock);
VIR_FREE(mon->buffer);
- VIR_FREE(mon);
-}
-
-int qemuMonitorRef(qemuMonitorPtr mon)
-{
- mon->refs++;
- PROBE(QEMU_MONITOR_REF,
- "mon=%p refs=%d", mon, mon->refs);
- return mon->refs;
-}
-
-int qemuMonitorUnref(qemuMonitorPtr mon)
-{
- mon->refs--;
-
- PROBE(QEMU_MONITOR_UNREF,
- "mon=%p refs=%d", mon, mon->refs);
- if (mon->refs == 0) {
- qemuMonitorUnlock(mon);
- qemuMonitorFree(mon);
- return 0;
- }
-
- return mon->refs;
}
-static void
-qemuMonitorUnwatch(void *monitor)
-{
- qemuMonitorPtr mon = monitor;
-
- qemuMonitorLock(mon);
- if (qemuMonitorUnref(mon) > 0)
- qemuMonitorUnlock(mon);
-}
static int
qemuMonitorOpenUnix(const char *monitor, pid_t cpid)
bool error = false;
bool eof = false;
+ virObjectRef(mon);
+
/* lock access to the monitor and protect fd */
qemuMonitorLock(mon);
- qemuMonitorRef(mon);
#if DEBUG_IO
VIR_DEBUG("Monitor %p I/O on watch %d fd %d events %d", mon, watch, fd, events);
#endif
/* Make sure anyone waiting wakes up now */
virCondSignal(&mon->notify);
- if (qemuMonitorUnref(mon) > 0)
- qemuMonitorUnlock(mon);
+ qemuMonitorUnlock(mon);
+ virObjectUnref(mon);
VIR_DEBUG("Triggering EOF callback");
(eofNotify)(mon, vm);
} else if (error) {
/* Make sure anyone waiting wakes up now */
virCondSignal(&mon->notify);
- if (qemuMonitorUnref(mon) > 0)
- qemuMonitorUnlock(mon);
+ qemuMonitorUnlock(mon);
+ virObjectUnref(mon);
VIR_DEBUG("Triggering error callback");
(errorNotify)(mon, vm);
} else {
- if (qemuMonitorUnref(mon) > 0)
- qemuMonitorUnlock(mon);
+ qemuMonitorUnlock(mon);
+ virObjectUnref(mon);
}
}
return NULL;
}
- if (VIR_ALLOC(mon) < 0) {
- virReportOOMError();
+ if (qemuMonitorInitialize() < 0)
+ return NULL;
+
+ if (!(mon = virObjectNew(qemuMonitorClass)))
return NULL;
- }
if (virMutexInit(&mon->lock) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
return NULL;
}
mon->fd = -1;
- mon->refs = 1;
mon->vm = vm;
mon->json = json;
mon->cb = cb;
VIR_EVENT_HANDLE_ERROR |
VIR_EVENT_HANDLE_READABLE,
qemuMonitorIO,
- mon, qemuMonitorUnwatch)) < 0) {
+ mon,
+ virObjectFreeCallback)) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("unable to register monitor events"));
goto cleanup;
}
- qemuMonitorRef(mon);
+ virObjectRef(mon);
PROBE(QEMU_MONITOR_NEW,
"mon=%p refs=%d fd=%d",
- mon, mon->refs, mon->fd);
+ mon, mon->object.refs, mon->fd);
qemuMonitorUnlock(mon);
return mon;
qemuMonitorLock(mon);
PROBE(QEMU_MONITOR_CLOSE,
- "mon=%p refs=%d", mon, mon->refs);
+ "mon=%p refs=%d", mon, mon->object.refs);
if (mon->fd >= 0) {
if (mon->watch)
virCondSignal(&mon->notify);
}
- if (qemuMonitorUnref(mon) > 0)
- qemuMonitorUnlock(mon);
+ qemuMonitorUnlock(mon);
+ virObjectUnref(mon);
}
/* Ensure proper locking around callbacks. */
#define QEMU_MONITOR_CALLBACK(mon, ret, callback, ...) \
do { \
- qemuMonitorRef(mon); \
+ virObjectRef(mon); \
qemuMonitorUnlock(mon); \
if ((mon)->cb && (mon)->cb->callback) \
(ret) = ((mon)->cb->callback)(mon, __VA_ARGS__); \
qemuMonitorLock(mon); \
- ignore_value(qemuMonitorUnref(mon)); \
+ virObjectUnref(mon); \
} while (0)
int qemuMonitorGetDiskSecret(qemuMonitorPtr mon,