---
src/qemu/qemu_domain.c | 26 +-----------
src/qemu/qemu_monitor.c | 106 ++++++++++++++++++++++++++--------------------
src/qemu/qemu_monitor.h | 4 +-
3 files changed, 64 insertions(+), 72 deletions(-)
diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c
index 8a2b9cc..e056ef0 100644
--- a/src/qemu/qemu_domain.c
+++ b/src/qemu/qemu_domain.c
@@ -566,7 +566,6 @@ void qemuDomainObjEnterMonitor(virDomainObjPtr obj)
qemuDomainObjPrivatePtr priv = obj->privateData;
qemuMonitorLock(priv->mon);
- qemuMonitorRef(priv->mon);
virDomainObjUnlock(obj);
}
@@ -578,19 +577,9 @@ void qemuDomainObjEnterMonitor(virDomainObjPtr obj)
void qemuDomainObjExitMonitor(virDomainObjPtr obj)
{
qemuDomainObjPrivatePtr priv = obj->privateData;
- int refs;
-
- refs = qemuMonitorUnref(priv->mon);
-
- if (refs > 0)
- qemuMonitorUnlock(priv->mon);
+ qemuMonitorUnlock(priv->mon);
virDomainObjLock(obj);
-
- if (refs == 0) {
- virDomainObjUnref(obj);
- priv->mon = NULL;
- }
}
@@ -608,7 +597,6 @@ void qemuDomainObjEnterMonitorWithDriver(struct qemud_driver *driver,
qemuDomainObjPrivatePtr priv = obj->privateData;
qemuMonitorLock(priv->mon);
- qemuMonitorRef(priv->mon);
virDomainObjUnlock(obj);
qemuDriverUnlock(driver);
}
@@ -623,20 +611,10 @@ void qemuDomainObjExitMonitorWithDriver(struct qemud_driver
*driver,
virDomainObjPtr obj)
{
qemuDomainObjPrivatePtr priv = obj->privateData;
- int refs;
-
- refs = qemuMonitorUnref(priv->mon);
-
- if (refs > 0)
- qemuMonitorUnlock(priv->mon);
+ qemuMonitorUnlock(priv->mon);
qemuDriverLock(driver);
virDomainObjLock(obj);
-
- if (refs == 0) {
- virDomainObjUnref(obj);
- priv->mon = NULL;
- }
}
void qemuDomainObjEnterRemoteWithDriver(struct qemud_driver *driver,
diff --git a/src/qemu/qemu_monitor.c b/src/qemu/qemu_monitor.c
index 37401df..d37265e 100644
--- a/src/qemu/qemu_monitor.c
+++ b/src/qemu/qemu_monitor.c
@@ -37,6 +37,7 @@
#include "memory.h"
#include "logging.h"
#include "files.h"
+#include "object.h"
#define VIR_FROM_THIS VIR_FROM_QEMU
@@ -44,11 +45,10 @@
#define DEBUG_RAW_IO 0
struct _qemuMonitor {
+ virObject obj;
virMutex lock; /* also used to protect fd */
virCond notify;
- int refs;
-
int fd;
int watch;
int hasSendFD;
@@ -202,35 +202,66 @@ void qemuMonitorUnlock(qemuMonitorPtr mon)
}
-static void qemuMonitorFree(qemuMonitorPtr mon)
+static void doMonitorFree(virObjectPtr obj)
{
+ qemuMonitorPtr mon = (qemuMonitorPtr)obj;
+
VIR_DEBUG("mon=%p", mon);
if (mon->cb && mon->cb->destroy)
(mon->cb->destroy)(mon, mon->vm);
- if (virCondDestroy(&mon->notify) < 0)
- {}
+ ignore_value(virCondDestroy(&mon->notify));
virMutexDestroy(&mon->lock);
VIR_FREE(mon->buffer);
VIR_FREE(mon);
}
-int qemuMonitorRef(qemuMonitorPtr mon)
+static qemuMonitorPtr qemuMonitorAlloc(void)
{
- mon->refs++;
- return mon->refs;
+ qemuMonitorPtr mon;
+
+ if (VIR_ALLOC(mon) < 0) {
+ virReportOOMError();
+ return NULL;
+ }
+
+ if (virObjectInit(&mon->obj, doMonitorFree)) {
+ VIR_FREE(mon);
+ return NULL;
+ }
+
+ if (virMutexInit(&mon->lock) < 0) {
+ qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("cannot initialize monitor mutex"));
+ VIR_FREE(mon);
+ return NULL;
+ }
+
+ if (virCondInit(&mon->notify) < 0) {
+ qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("cannot initialize monitor condition"));
+ virMutexDestroy(&mon->lock);
+ VIR_FREE(mon);
+ return NULL;
+ }
+
+ mon->fd = -1;
+
+ return mon;
}
-int qemuMonitorUnref(qemuMonitorPtr mon)
+static void qemuMonitorFree(qemuMonitorPtr mon)
{
- mon->refs--;
+ virObjectUnref(&mon->obj);
+}
- if (mon->refs == 0) {
- qemuMonitorUnlock(mon);
- qemuMonitorFree(mon);
- return 0;
- }
+void qemuMonitorRef(qemuMonitorPtr mon)
+{
+ virObjectRef(&mon->obj);
+}
- return mon->refs;
+void qemuMonitorUnref(qemuMonitorPtr mon)
+{
+ virObjectUnref(&mon->obj);
}
static void
@@ -238,7 +269,6 @@ qemuMonitorUnwatch(void *monitor)
{
qemuMonitorPtr mon = monitor;
- qemuMonitorLock(mon);
qemuMonitorUnref(mon);
}
@@ -519,7 +549,6 @@ qemuMonitorIO(int watch, int fd, int events, void *opaque) {
/* 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
@@ -587,13 +616,11 @@ qemuMonitorIO(int watch, int fd, int events, void *opaque) {
virDomainObjPtr vm = mon->vm;
/* Make sure anyone waiting wakes up now */
virCondSignal(&mon->notify);
- if (qemuMonitorUnref(mon) > 0)
- qemuMonitorUnlock(mon);
+ qemuMonitorUnlock(mon);
VIR_DEBUG("Triggering EOF callback error? %d", failed);
(eofNotify)(mon, vm, failed);
} else {
- if (qemuMonitorUnref(mon) > 0)
- qemuMonitorUnlock(mon);
+ qemuMonitorUnlock(mon);
}
}
@@ -612,30 +639,13 @@ qemuMonitorOpen(virDomainObjPtr vm,
return NULL;
}
- if (VIR_ALLOC(mon) < 0) {
- virReportOOMError();
+ mon = qemuMonitorAlloc();
+ if (!mon)
return NULL;
- }
- if (virMutexInit(&mon->lock) < 0) {
- qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("cannot initialize monitor mutex"));
- VIR_FREE(mon);
- return NULL;
- }
- if (virCondInit(&mon->notify) < 0) {
- qemuReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("cannot initialize monitor condition"));
- virMutexDestroy(&mon->lock);
- VIR_FREE(mon);
- return NULL;
- }
- mon->fd = -1;
- mon->refs = 1;
mon->vm = vm;
mon->json = json;
mon->cb = cb;
- qemuMonitorLock(mon);
switch (config->type) {
case VIR_DOMAIN_CHR_TYPE_UNIX:
@@ -668,6 +678,12 @@ qemuMonitorOpen(virDomainObjPtr vm,
}
+ /* mon will be accessed by qemuMonitorIO which is called in
+ * event thread, so ref it before passing it to the thread.
+ *
+ * Note: mon is unrefed in qemuMonitorUnwatch
+ */
+ qemuMonitorRef(mon);
if ((mon->watch = virEventAddHandle(mon->fd,
VIR_EVENT_HANDLE_HANGUP |
VIR_EVENT_HANDLE_ERROR |
@@ -678,10 +694,8 @@ qemuMonitorOpen(virDomainObjPtr vm,
_("unable to register monitor events"));
goto cleanup;
}
- qemuMonitorRef(mon);
VIR_DEBUG("New mon %p fd =%d watch=%d", mon, mon->fd, mon->watch);
- qemuMonitorUnlock(mon);
return mon;
@@ -692,8 +706,8 @@ cleanup:
* so kill the callbacks now.
*/
mon->cb = NULL;
- qemuMonitorUnlock(mon);
qemuMonitorClose(mon);
+ qemuMonitorFree(mon);
return NULL;
}
@@ -713,8 +727,8 @@ void qemuMonitorClose(qemuMonitorPtr mon)
VIR_FORCE_CLOSE(mon->fd);
}
- if (qemuMonitorUnref(mon) > 0)
- qemuMonitorUnlock(mon);
+ qemuMonitorUnlock(mon);
+ qemuMonitorFree(mon);
}
diff --git a/src/qemu/qemu_monitor.h b/src/qemu/qemu_monitor.h
index ece15a8..4d6b12e 100644
--- a/src/qemu/qemu_monitor.h
+++ b/src/qemu/qemu_monitor.h
@@ -130,8 +130,8 @@ int qemuMonitorSetCapabilities(qemuMonitorPtr mon);
void qemuMonitorLock(qemuMonitorPtr mon);
void qemuMonitorUnlock(qemuMonitorPtr mon);
-int qemuMonitorRef(qemuMonitorPtr mon);
-int qemuMonitorUnref(qemuMonitorPtr mon);
+void qemuMonitorRef(qemuMonitorPtr mon);
+void qemuMonitorUnref(qemuMonitorPtr mon);
/* These APIs are for use by the internal Text/JSON monitor impl code only */
int qemuMonitorSend(qemuMonitorPtr mon,
--
1.7.3.1
--
Thanks,
Hu Tao