From: "Daniel P. Berrange" <berrange@xxxxxxxxxx> Make qemuAgentPtr and qemuMonitorPtr types use the virObject APIs for reference counting Signed-off-by: Daniel P. Berrange <berrange@xxxxxxxxxx> --- src/qemu/qemu_agent.c | 86 ++++++++++++++++++----------------------- src/qemu/qemu_agent.h | 3 -- src/qemu/qemu_domain.c | 22 +++++------ src/qemu/qemu_monitor.c | 97 ++++++++++++++++++++--------------------------- src/qemu/qemu_monitor.h | 3 -- 5 files changed, 89 insertions(+), 122 deletions(-) diff --git a/src/qemu/qemu_agent.c b/src/qemu/qemu_agent.c index 14bf11b..15af758 100644 --- a/src/qemu/qemu_agent.c +++ b/src/qemu/qemu_agent.c @@ -40,6 +40,7 @@ #include "json.h" #include "virfile.h" #include "virtime.h" +#include "virobject.h" #define VIR_FROM_THIS VIR_FROM_QEMU @@ -80,11 +81,11 @@ struct _qemuAgentMessage { struct _qemuAgent { + virObject object; + virMutex lock; /* also used to protect fd */ virCond notify; - int refs; - int fd; int watch; @@ -114,6 +115,22 @@ struct _qemuAgent { 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 * @@ -146,45 +163,15 @@ void qemuAgentUnlock(qemuAgentPtr mon) } -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 @@ -599,9 +586,9 @@ qemuAgentIO(int watch, int fd, int events, void *opaque) { 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 @@ -704,8 +691,8 @@ qemuAgentIO(int watch, int fd, int events, void *opaque) { /* 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) { @@ -715,13 +702,13 @@ qemuAgentIO(int watch, int fd, int events, void *opaque) { /* 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); } } @@ -739,10 +726,11 @@ qemuAgentOpen(virDomainObjPtr vm, 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", @@ -758,7 +746,6 @@ qemuAgentOpen(virDomainObjPtr vm, return NULL; } mon->fd = -1; - mon->refs = 1; mon->vm = vm; mon->cb = cb; qemuAgentLock(mon); @@ -791,12 +778,13 @@ qemuAgentOpen(virDomainObjPtr vm, 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); @@ -837,9 +825,9 @@ void qemuAgentClose(qemuAgentPtr 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) diff --git a/src/qemu/qemu_agent.h b/src/qemu/qemu_agent.h index 860e7e5..2fdebb2 100644 --- a/src/qemu/qemu_agent.h +++ b/src/qemu/qemu_agent.h @@ -50,9 +50,6 @@ qemuAgentPtr qemuAgentOpen(virDomainObjPtr vm, void qemuAgentLock(qemuAgentPtr mon); void qemuAgentUnlock(qemuAgentPtr mon); -int qemuAgentRef(qemuAgentPtr mon); -int qemuAgentUnref(qemuAgentPtr mon) ATTRIBUTE_RETURN_CHECK; - void qemuAgentClose(qemuAgentPtr mon); typedef enum { diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index 4acbb20..f7cbe7f 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -994,7 +994,7 @@ qemuDomainObjEnterMonitorInternal(struct qemud_driver *driver, } qemuMonitorLock(priv->mon); - qemuMonitorRef(priv->mon); + virObjectRef(priv->mon); ignore_value(virTimeMillisNow(&priv->monStart)); virDomainObjUnlock(obj); if (driver_locked) @@ -1009,11 +1009,11 @@ qemuDomainObjExitMonitorInternal(struct qemud_driver *driver, 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) @@ -1021,9 +1021,8 @@ qemuDomainObjExitMonitorInternal(struct qemud_driver *driver, virDomainObjLock(obj); priv->monStart = 0; - if (refs == 0) { + if (!hasRefs) priv->mon = NULL; - } if (priv->job.active == QEMU_JOB_ASYNC_NESTED) { qemuDomainObjResetJob(priv); @@ -1118,7 +1117,7 @@ qemuDomainObjEnterAgentInternal(struct qemud_driver *driver, qemuDomainObjPrivatePtr priv = obj->privateData; qemuAgentLock(priv->agent); - qemuAgentRef(priv->agent); + virObjectRef(priv->agent); ignore_value(virTimeMillisNow(&priv->agentStart)); virDomainObjUnlock(obj); if (driver_locked) @@ -1133,11 +1132,11 @@ qemuDomainObjExitAgentInternal(struct qemud_driver *driver, 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) @@ -1145,9 +1144,8 @@ qemuDomainObjExitAgentInternal(struct qemud_driver *driver, virDomainObjLock(obj); priv->agentStart = 0; - if (refs == 0) { + if (!hasRefs) priv->agent = NULL; - } } /* diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c index 20395b0..b0f3bb6 100644 --- a/src/qemu/qemu_monitor.c +++ b/src/qemu/qemu_monitor.c @@ -36,6 +36,7 @@ #include "memory.h" #include "logging.h" #include "virfile.h" +#include "virobject.h" #ifdef WITH_DTRACE_PROBES # include "libvirt_qemu_probes.h" @@ -47,11 +48,11 @@ #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; @@ -80,6 +81,21 @@ struct _qemuMonitor { 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, @@ -224,8 +240,10 @@ void qemuMonitorUnlock(qemuMonitorPtr mon) } -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); @@ -233,41 +251,8 @@ static void qemuMonitorFree(qemuMonitorPtr mon) {} 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) @@ -567,9 +552,10 @@ qemuMonitorIO(int watch, int fd, int events, void *opaque) { 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 @@ -667,8 +653,8 @@ qemuMonitorIO(int watch, int fd, int events, void *opaque) { /* 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) { @@ -678,13 +664,13 @@ qemuMonitorIO(int watch, int fd, int events, void *opaque) { /* 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); } } @@ -703,10 +689,11 @@ qemuMonitorOpen(virDomainObjPtr vm, 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", @@ -722,7 +709,6 @@ qemuMonitorOpen(virDomainObjPtr vm, return NULL; } mon->fd = -1; - mon->refs = 1; mon->vm = vm; mon->json = json; mon->cb = cb; @@ -764,16 +750,17 @@ qemuMonitorOpen(virDomainObjPtr vm, 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; @@ -798,7 +785,7 @@ void qemuMonitorClose(qemuMonitorPtr 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) @@ -827,8 +814,8 @@ void qemuMonitorClose(qemuMonitorPtr mon) virCondSignal(&mon->notify); } - if (qemuMonitorUnref(mon) > 0) - qemuMonitorUnlock(mon); + qemuMonitorUnlock(mon); + virObjectUnref(mon); } @@ -919,12 +906,12 @@ cleanup: /* 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, diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h index 995948b..42f33d1 100644 --- a/src/qemu/qemu_monitor.h +++ b/src/qemu/qemu_monitor.h @@ -156,9 +156,6 @@ int qemuMonitorCheckHMP(qemuMonitorPtr mon, const char *cmd); void qemuMonitorLock(qemuMonitorPtr mon); void qemuMonitorUnlock(qemuMonitorPtr mon); -int qemuMonitorRef(qemuMonitorPtr mon); -int qemuMonitorUnref(qemuMonitorPtr mon) ATTRIBUTE_RETURN_CHECK; - int qemuMonitorSetLink(qemuMonitorPtr mon, const char *name, enum virDomainNetInterfaceLinkState state) ; -- 1.7.10.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list