Turn qemuAgentPtr and qemuMonitorPtr into virObjectPtr instances

Make qemuAgentPtr and qemuMonitorPtr types use the virObject APIs
for reference counting

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
This commit is contained in:
Daniel P. Berrange 2012-07-11 14:35:47 +01:00
parent 31cb030ab6
commit b57ee0921e
5 changed files with 89 additions and 122 deletions

View File

@ -40,6 +40,7 @@
#include "json.h" #include "json.h"
#include "virfile.h" #include "virfile.h"
#include "virtime.h" #include "virtime.h"
#include "virobject.h"
#define VIR_FROM_THIS VIR_FROM_QEMU #define VIR_FROM_THIS VIR_FROM_QEMU
@ -80,11 +81,11 @@ struct _qemuAgentMessage {
struct _qemuAgent { struct _qemuAgent {
virObject object;
virMutex lock; /* also used to protect fd */ virMutex lock; /* also used to protect fd */
virCond notify; virCond notify;
int refs;
int fd; int fd;
int watch; int watch;
@ -114,6 +115,22 @@ struct _qemuAgent {
qemuAgentEvent await_event; 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 #if DEBUG_RAW_IO
# include <c-ctype.h> # include <c-ctype.h>
static char * 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); VIR_DEBUG("mon=%p", mon);
if (mon->cb && mon->cb->destroy) if (mon->cb && mon->cb->destroy)
(mon->cb->destroy)(mon, mon->vm); (mon->cb->destroy)(mon, mon->vm);
ignore_value(virCondDestroy(&mon->notify)); ignore_value(virCondDestroy(&mon->notify));
virMutexDestroy(&mon->lock); virMutexDestroy(&mon->lock);
VIR_FREE(mon->buffer); 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 static int
@ -599,9 +586,9 @@ qemuAgentIO(int watch, int fd, int events, void *opaque) {
bool error = false; bool error = false;
bool eof = false; bool eof = false;
virObjectRef(mon);
/* lock access to the monitor and protect fd */ /* lock access to the monitor and protect fd */
qemuAgentLock(mon); qemuAgentLock(mon);
qemuAgentRef(mon);
#if DEBUG_IO #if DEBUG_IO
VIR_DEBUG("Agent %p I/O on watch %d fd %d events %d", mon, watch, fd, events); VIR_DEBUG("Agent %p I/O on watch %d fd %d events %d", mon, watch, fd, events);
#endif #endif
@ -704,8 +691,8 @@ qemuAgentIO(int watch, int fd, int events, void *opaque) {
/* Make sure anyone waiting wakes up now */ /* Make sure anyone waiting wakes up now */
virCondSignal(&mon->notify); virCondSignal(&mon->notify);
if (qemuAgentUnref(mon) > 0) qemuAgentUnlock(mon);
qemuAgentUnlock(mon); virObjectUnref(mon);
VIR_DEBUG("Triggering EOF callback"); VIR_DEBUG("Triggering EOF callback");
(eofNotify)(mon, vm); (eofNotify)(mon, vm);
} else if (error) { } else if (error) {
@ -715,13 +702,13 @@ qemuAgentIO(int watch, int fd, int events, void *opaque) {
/* Make sure anyone waiting wakes up now */ /* Make sure anyone waiting wakes up now */
virCondSignal(&mon->notify); virCondSignal(&mon->notify);
if (qemuAgentUnref(mon) > 0) qemuAgentUnlock(mon);
qemuAgentUnlock(mon); virObjectUnref(mon);
VIR_DEBUG("Triggering error callback"); VIR_DEBUG("Triggering error callback");
(errorNotify)(mon, vm); (errorNotify)(mon, vm);
} else { } else {
if (qemuAgentUnref(mon) > 0) qemuAgentUnlock(mon);
qemuAgentUnlock(mon); virObjectUnref(mon);
} }
} }
@ -739,10 +726,11 @@ qemuAgentOpen(virDomainObjPtr vm,
return NULL; return NULL;
} }
if (VIR_ALLOC(mon) < 0) { if (qemuAgentInitialize() < 0)
virReportOOMError(); return NULL;
if (!(mon = virObjectNew(qemuAgentClass)))
return NULL; return NULL;
}
if (virMutexInit(&mon->lock) < 0) { if (virMutexInit(&mon->lock) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
@ -758,7 +746,6 @@ qemuAgentOpen(virDomainObjPtr vm,
return NULL; return NULL;
} }
mon->fd = -1; mon->fd = -1;
mon->refs = 1;
mon->vm = vm; mon->vm = vm;
mon->cb = cb; mon->cb = cb;
qemuAgentLock(mon); qemuAgentLock(mon);
@ -791,12 +778,13 @@ qemuAgentOpen(virDomainObjPtr vm,
VIR_EVENT_HANDLE_WRITABLE : VIR_EVENT_HANDLE_WRITABLE :
0), 0),
qemuAgentIO, qemuAgentIO,
mon, qemuAgentUnwatch)) < 0) { mon,
virObjectFreeCallback)) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("unable to register monitor events")); _("unable to register monitor events"));
goto cleanup; goto cleanup;
} }
qemuAgentRef(mon); virObjectRef(mon);
VIR_DEBUG("New mon %p fd =%d watch=%d", mon, mon->fd, mon->watch); VIR_DEBUG("New mon %p fd =%d watch=%d", mon, mon->fd, mon->watch);
qemuAgentUnlock(mon); qemuAgentUnlock(mon);
@ -837,9 +825,9 @@ void qemuAgentClose(qemuAgentPtr mon)
mon->msg->finished = 1; mon->msg->finished = 1;
virCondSignal(&mon->notify); virCondSignal(&mon->notify);
} }
qemuAgentUnlock(mon);
if (qemuAgentUnref(mon) > 0) virObjectUnref(mon);
qemuAgentUnlock(mon);
} }
#define QEMU_AGENT_WAIT_TIME (1000ull * 5) #define QEMU_AGENT_WAIT_TIME (1000ull * 5)

View File

@ -50,9 +50,6 @@ qemuAgentPtr qemuAgentOpen(virDomainObjPtr vm,
void qemuAgentLock(qemuAgentPtr mon); void qemuAgentLock(qemuAgentPtr mon);
void qemuAgentUnlock(qemuAgentPtr mon); void qemuAgentUnlock(qemuAgentPtr mon);
int qemuAgentRef(qemuAgentPtr mon);
int qemuAgentUnref(qemuAgentPtr mon) ATTRIBUTE_RETURN_CHECK;
void qemuAgentClose(qemuAgentPtr mon); void qemuAgentClose(qemuAgentPtr mon);
typedef enum { typedef enum {

View File

@ -994,7 +994,7 @@ qemuDomainObjEnterMonitorInternal(struct qemud_driver *driver,
} }
qemuMonitorLock(priv->mon); qemuMonitorLock(priv->mon);
qemuMonitorRef(priv->mon); virObjectRef(priv->mon);
ignore_value(virTimeMillisNow(&priv->monStart)); ignore_value(virTimeMillisNow(&priv->monStart));
virDomainObjUnlock(obj); virDomainObjUnlock(obj);
if (driver_locked) if (driver_locked)
@ -1009,11 +1009,11 @@ qemuDomainObjExitMonitorInternal(struct qemud_driver *driver,
virDomainObjPtr obj) virDomainObjPtr obj)
{ {
qemuDomainObjPrivatePtr priv = obj->privateData; qemuDomainObjPrivatePtr priv = obj->privateData;
int refs; bool hasRefs;
refs = qemuMonitorUnref(priv->mon); hasRefs = virObjectUnref(priv->mon);
if (refs > 0) if (hasRefs)
qemuMonitorUnlock(priv->mon); qemuMonitorUnlock(priv->mon);
if (driver_locked) if (driver_locked)
@ -1021,9 +1021,8 @@ qemuDomainObjExitMonitorInternal(struct qemud_driver *driver,
virDomainObjLock(obj); virDomainObjLock(obj);
priv->monStart = 0; priv->monStart = 0;
if (refs == 0) { if (!hasRefs)
priv->mon = NULL; priv->mon = NULL;
}
if (priv->job.active == QEMU_JOB_ASYNC_NESTED) { if (priv->job.active == QEMU_JOB_ASYNC_NESTED) {
qemuDomainObjResetJob(priv); qemuDomainObjResetJob(priv);
@ -1118,7 +1117,7 @@ qemuDomainObjEnterAgentInternal(struct qemud_driver *driver,
qemuDomainObjPrivatePtr priv = obj->privateData; qemuDomainObjPrivatePtr priv = obj->privateData;
qemuAgentLock(priv->agent); qemuAgentLock(priv->agent);
qemuAgentRef(priv->agent); virObjectRef(priv->agent);
ignore_value(virTimeMillisNow(&priv->agentStart)); ignore_value(virTimeMillisNow(&priv->agentStart));
virDomainObjUnlock(obj); virDomainObjUnlock(obj);
if (driver_locked) if (driver_locked)
@ -1133,11 +1132,11 @@ qemuDomainObjExitAgentInternal(struct qemud_driver *driver,
virDomainObjPtr obj) virDomainObjPtr obj)
{ {
qemuDomainObjPrivatePtr priv = obj->privateData; qemuDomainObjPrivatePtr priv = obj->privateData;
int refs; bool hasRefs;
refs = qemuAgentUnref(priv->agent); hasRefs = virObjectUnref(priv->agent);
if (refs > 0) if (hasRefs)
qemuAgentUnlock(priv->agent); qemuAgentUnlock(priv->agent);
if (driver_locked) if (driver_locked)
@ -1145,9 +1144,8 @@ qemuDomainObjExitAgentInternal(struct qemud_driver *driver,
virDomainObjLock(obj); virDomainObjLock(obj);
priv->agentStart = 0; priv->agentStart = 0;
if (refs == 0) { if (!hasRefs)
priv->agent = NULL; priv->agent = NULL;
}
} }
/* /*

View File

@ -36,6 +36,7 @@
#include "memory.h" #include "memory.h"
#include "logging.h" #include "logging.h"
#include "virfile.h" #include "virfile.h"
#include "virobject.h"
#ifdef WITH_DTRACE_PROBES #ifdef WITH_DTRACE_PROBES
# include "libvirt_qemu_probes.h" # include "libvirt_qemu_probes.h"
@ -47,11 +48,11 @@
#define DEBUG_RAW_IO 0 #define DEBUG_RAW_IO 0
struct _qemuMonitor { struct _qemuMonitor {
virObject object;
virMutex lock; /* also used to protect fd */ virMutex lock; /* also used to protect fd */
virCond notify; virCond notify;
int refs;
int fd; int fd;
int watch; int watch;
int hasSendFD; int hasSendFD;
@ -80,6 +81,21 @@ struct _qemuMonitor {
unsigned json_hmp: 1; 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, VIR_ENUM_IMPL(qemuMonitorMigrationStatus,
QEMU_MONITOR_MIGRATION_STATUS_LAST, 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); VIR_DEBUG("mon=%p", mon);
if (mon->cb && mon->cb->destroy) if (mon->cb && mon->cb->destroy)
(mon->cb->destroy)(mon, mon->vm); (mon->cb->destroy)(mon, mon->vm);
@ -233,41 +251,8 @@ static void qemuMonitorFree(qemuMonitorPtr mon)
{} {}
virMutexDestroy(&mon->lock); virMutexDestroy(&mon->lock);
VIR_FREE(mon->buffer); 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 static int
qemuMonitorOpenUnix(const char *monitor, pid_t cpid) qemuMonitorOpenUnix(const char *monitor, pid_t cpid)
@ -567,9 +552,10 @@ qemuMonitorIO(int watch, int fd, int events, void *opaque) {
bool error = false; bool error = false;
bool eof = false; bool eof = false;
virObjectRef(mon);
/* lock access to the monitor and protect fd */ /* lock access to the monitor and protect fd */
qemuMonitorLock(mon); qemuMonitorLock(mon);
qemuMonitorRef(mon);
#if DEBUG_IO #if DEBUG_IO
VIR_DEBUG("Monitor %p I/O on watch %d fd %d events %d", mon, watch, fd, events); VIR_DEBUG("Monitor %p I/O on watch %d fd %d events %d", mon, watch, fd, events);
#endif #endif
@ -667,8 +653,8 @@ qemuMonitorIO(int watch, int fd, int events, void *opaque) {
/* Make sure anyone waiting wakes up now */ /* Make sure anyone waiting wakes up now */
virCondSignal(&mon->notify); virCondSignal(&mon->notify);
if (qemuMonitorUnref(mon) > 0) qemuMonitorUnlock(mon);
qemuMonitorUnlock(mon); virObjectUnref(mon);
VIR_DEBUG("Triggering EOF callback"); VIR_DEBUG("Triggering EOF callback");
(eofNotify)(mon, vm); (eofNotify)(mon, vm);
} else if (error) { } else if (error) {
@ -678,13 +664,13 @@ qemuMonitorIO(int watch, int fd, int events, void *opaque) {
/* Make sure anyone waiting wakes up now */ /* Make sure anyone waiting wakes up now */
virCondSignal(&mon->notify); virCondSignal(&mon->notify);
if (qemuMonitorUnref(mon) > 0) qemuMonitorUnlock(mon);
qemuMonitorUnlock(mon); virObjectUnref(mon);
VIR_DEBUG("Triggering error callback"); VIR_DEBUG("Triggering error callback");
(errorNotify)(mon, vm); (errorNotify)(mon, vm);
} else { } else {
if (qemuMonitorUnref(mon) > 0) qemuMonitorUnlock(mon);
qemuMonitorUnlock(mon); virObjectUnref(mon);
} }
} }
@ -703,10 +689,11 @@ qemuMonitorOpen(virDomainObjPtr vm,
return NULL; return NULL;
} }
if (VIR_ALLOC(mon) < 0) { if (qemuMonitorInitialize() < 0)
virReportOOMError(); return NULL;
if (!(mon = virObjectNew(qemuMonitorClass)))
return NULL; return NULL;
}
if (virMutexInit(&mon->lock) < 0) { if (virMutexInit(&mon->lock) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
@ -722,7 +709,6 @@ qemuMonitorOpen(virDomainObjPtr vm,
return NULL; return NULL;
} }
mon->fd = -1; mon->fd = -1;
mon->refs = 1;
mon->vm = vm; mon->vm = vm;
mon->json = json; mon->json = json;
mon->cb = cb; mon->cb = cb;
@ -764,16 +750,17 @@ qemuMonitorOpen(virDomainObjPtr vm,
VIR_EVENT_HANDLE_ERROR | VIR_EVENT_HANDLE_ERROR |
VIR_EVENT_HANDLE_READABLE, VIR_EVENT_HANDLE_READABLE,
qemuMonitorIO, qemuMonitorIO,
mon, qemuMonitorUnwatch)) < 0) { mon,
virObjectFreeCallback)) < 0) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s", virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("unable to register monitor events")); _("unable to register monitor events"));
goto cleanup; goto cleanup;
} }
qemuMonitorRef(mon); virObjectRef(mon);
PROBE(QEMU_MONITOR_NEW, PROBE(QEMU_MONITOR_NEW,
"mon=%p refs=%d fd=%d", "mon=%p refs=%d fd=%d",
mon, mon->refs, mon->fd); mon, mon->object.refs, mon->fd);
qemuMonitorUnlock(mon); qemuMonitorUnlock(mon);
return mon; return mon;
@ -798,7 +785,7 @@ void qemuMonitorClose(qemuMonitorPtr mon)
qemuMonitorLock(mon); qemuMonitorLock(mon);
PROBE(QEMU_MONITOR_CLOSE, 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->fd >= 0) {
if (mon->watch) if (mon->watch)
@ -827,8 +814,8 @@ void qemuMonitorClose(qemuMonitorPtr mon)
virCondSignal(&mon->notify); virCondSignal(&mon->notify);
} }
if (qemuMonitorUnref(mon) > 0) qemuMonitorUnlock(mon);
qemuMonitorUnlock(mon); virObjectUnref(mon);
} }
@ -919,12 +906,12 @@ cleanup:
/* Ensure proper locking around callbacks. */ /* Ensure proper locking around callbacks. */
#define QEMU_MONITOR_CALLBACK(mon, ret, callback, ...) \ #define QEMU_MONITOR_CALLBACK(mon, ret, callback, ...) \
do { \ do { \
qemuMonitorRef(mon); \ virObjectRef(mon); \
qemuMonitorUnlock(mon); \ qemuMonitorUnlock(mon); \
if ((mon)->cb && (mon)->cb->callback) \ if ((mon)->cb && (mon)->cb->callback) \
(ret) = ((mon)->cb->callback)(mon, __VA_ARGS__); \ (ret) = ((mon)->cb->callback)(mon, __VA_ARGS__); \
qemuMonitorLock(mon); \ qemuMonitorLock(mon); \
ignore_value(qemuMonitorUnref(mon)); \ virObjectUnref(mon); \
} while (0) } while (0)
int qemuMonitorGetDiskSecret(qemuMonitorPtr mon, int qemuMonitorGetDiskSecret(qemuMonitorPtr mon,

View File

@ -156,9 +156,6 @@ int qemuMonitorCheckHMP(qemuMonitorPtr mon, const char *cmd);
void qemuMonitorLock(qemuMonitorPtr mon); void qemuMonitorLock(qemuMonitorPtr mon);
void qemuMonitorUnlock(qemuMonitorPtr mon); void qemuMonitorUnlock(qemuMonitorPtr mon);
int qemuMonitorRef(qemuMonitorPtr mon);
int qemuMonitorUnref(qemuMonitorPtr mon) ATTRIBUTE_RETURN_CHECK;
int qemuMonitorSetLink(qemuMonitorPtr mon, int qemuMonitorSetLink(qemuMonitorPtr mon,
const char *name, const char *name,
enum virDomainNetInterfaceLinkState state) ; enum virDomainNetInterfaceLinkState state) ;