From 85ed303bfe1f67a4c18ffe51916e73cffd7d9e9b Mon Sep 17 00:00:00 2001 From: Anthony Liguori Date: Mon, 12 Dec 2011 14:29:25 -0600 Subject: qom: add a reference count to qdev objects To ensure that a device isn't removed from the graph until all of its links are broken. Signed-off-by: Anthony Liguori --- hw/qdev.c | 16 ++++++++++++++++ hw/qdev.h | 26 ++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/hw/qdev.c b/hw/qdev.c index 106407f226..fdc984312c 100644 --- a/hw/qdev.c +++ b/hw/qdev.c @@ -323,6 +323,11 @@ int qdev_unplug(DeviceState *dev) } assert(dev->info->unplug != NULL); + if (dev->ref != 0) { + qerror_report(QERR_DEVICE_IN_USE, dev->id?:""); + return -1; + } + qdev_hot_removed = true; return dev->info->unplug(dev); @@ -962,3 +967,14 @@ char* qdev_get_fw_dev_path(DeviceState *dev) return strdup(path); } + +void qdev_ref(DeviceState *dev) +{ + dev->ref++; +} + +void qdev_unref(DeviceState *dev) +{ + g_assert(dev->ref > 0); + dev->ref--; +} diff --git a/hw/qdev.h b/hw/qdev.h index 36a4198c89..2397b4e84c 100644 --- a/hw/qdev.h +++ b/hw/qdev.h @@ -45,6 +45,12 @@ struct DeviceState { QTAILQ_ENTRY(DeviceState) sibling; int instance_id_alias; int alias_required_for_version; + + /** + * This tracks the number of references between devices. See @qdev_ref for + * more information. + */ + uint32_t ref; }; typedef void (*bus_dev_printfn)(Monitor *mon, DeviceState *dev, int indent); @@ -329,4 +335,24 @@ char *qdev_get_fw_dev_path(DeviceState *dev); /* This is a nasty hack to allow passing a NULL bus to qdev_create. */ extern struct BusInfo system_bus_info; +/** + * @qdev_ref + * + * Increase the reference count of a device. A device cannot be freed as long + * as its reference count is greater than zero. + * + * @dev - the device + */ +void qdev_ref(DeviceState *dev); + +/** + * @qdef_unref + * + * Decrease the reference count of a device. A device cannot be freed as long + * as its reference count is greater than zero. + * + * @dev - the device + */ +void qdev_unref(DeviceState *dev); + #endif -- cgit v1.2.1