From a776fad370203703fc6cc685ce1931077fbee71c Mon Sep 17 00:00:00 2001 From: "Daniel P. Berrange" Date: Tue, 20 Jan 2009 12:14:03 +0000 Subject: [PATCH] Add public APIs for ref counting on public objects --- ChangeLog | 8 ++ include/libvirt/libvirt.h | 6 ++ include/libvirt/libvirt.h.in | 6 ++ src/libvirt.c | 183 +++++++++++++++++++++++++++++++++++ src/libvirt_public.syms | 12 ++- 5 files changed, 214 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index e166eaa2a6..0ed5708cca 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +Tue Jan 20 12:08:53 GMT 2009 Daniel P. Berrange + + * include/libvirt/libvirt.h, include/libvirt/libvirt.h.in, + src/libvirt.c, src/libvirt_public.syms: Add new ref counting + APIs for public objects: virConnectRef, virDomainRef, + virNetworkRef, virStoragePoolRef, virStorageVolRef, + virNodeDeviceRef + Tue Jan 20 12:03:53 GMT 2009 Daniel P. Berrange * tests/cpuset, tests/read-bufsiz, tests/start, tests/undefine, diff --git a/include/libvirt/libvirt.h b/include/libvirt/libvirt.h index 97b448993b..29115da5fd 100644 --- a/include/libvirt/libvirt.h +++ b/include/libvirt/libvirt.h @@ -396,6 +396,7 @@ virConnectPtr virConnectOpenReadOnly (const char *name); virConnectPtr virConnectOpenAuth (const char *name, virConnectAuthPtr auth, int flags); +int virConnectRef (virConnectPtr conn); int virConnectClose (virConnectPtr conn); const char * virConnectGetType (virConnectPtr conn); int virConnectGetVersion (virConnectPtr conn, @@ -453,6 +454,7 @@ int virDomainShutdown (virDomainPtr domain); int virDomainReboot (virDomainPtr domain, unsigned int flags); int virDomainDestroy (virDomainPtr domain); +int virDomainRef (virDomainPtr domain); int virDomainFree (virDomainPtr domain); /* @@ -765,6 +767,7 @@ int virNetworkCreate (virNetworkPtr network); * Network destroy/free */ int virNetworkDestroy (virNetworkPtr network); +int virNetworkRef (virNetworkPtr network); int virNetworkFree (virNetworkPtr network); /* @@ -925,6 +928,7 @@ int virStoragePoolCreate (virStoragePoolPtr pool, int virStoragePoolDestroy (virStoragePoolPtr pool); int virStoragePoolDelete (virStoragePoolPtr pool, unsigned int flags); +int virStoragePoolRef (virStoragePoolPtr pool); int virStoragePoolFree (virStoragePoolPtr pool); int virStoragePoolRefresh (virStoragePoolPtr pool, unsigned int flags); @@ -978,6 +982,7 @@ virStorageVolPtr virStorageVolCreateXML (virStoragePoolPtr pool, unsigned int flags); int virStorageVolDelete (virStorageVolPtr vol, unsigned int flags); +int virStorageVolRef (virStorageVolPtr vol); int virStorageVolFree (virStorageVolPtr vol); int virStorageVolGetInfo (virStorageVolPtr vol, @@ -1045,6 +1050,7 @@ int virNodeDeviceListCaps (virNodeDevicePtr dev, char * virNodeDeviceGetXMLDesc (virNodeDevicePtr dev, unsigned int flags); +int virNodeDeviceRef (virNodeDevicePtr dev); int virNodeDeviceFree (virNodeDevicePtr dev); /* diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index fc322e6b0f..af97bfd35e 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -396,6 +396,7 @@ virConnectPtr virConnectOpenReadOnly (const char *name); virConnectPtr virConnectOpenAuth (const char *name, virConnectAuthPtr auth, int flags); +int virConnectRef (virConnectPtr conn); int virConnectClose (virConnectPtr conn); const char * virConnectGetType (virConnectPtr conn); int virConnectGetVersion (virConnectPtr conn, @@ -453,6 +454,7 @@ int virDomainShutdown (virDomainPtr domain); int virDomainReboot (virDomainPtr domain, unsigned int flags); int virDomainDestroy (virDomainPtr domain); +int virDomainRef (virDomainPtr domain); int virDomainFree (virDomainPtr domain); /* @@ -765,6 +767,7 @@ int virNetworkCreate (virNetworkPtr network); * Network destroy/free */ int virNetworkDestroy (virNetworkPtr network); +int virNetworkRef (virNetworkPtr network); int virNetworkFree (virNetworkPtr network); /* @@ -925,6 +928,7 @@ int virStoragePoolCreate (virStoragePoolPtr pool, int virStoragePoolDestroy (virStoragePoolPtr pool); int virStoragePoolDelete (virStoragePoolPtr pool, unsigned int flags); +int virStoragePoolRef (virStoragePoolPtr pool); int virStoragePoolFree (virStoragePoolPtr pool); int virStoragePoolRefresh (virStoragePoolPtr pool, unsigned int flags); @@ -978,6 +982,7 @@ virStorageVolPtr virStorageVolCreateXML (virStoragePoolPtr pool, unsigned int flags); int virStorageVolDelete (virStorageVolPtr vol, unsigned int flags); +int virStorageVolRef (virStorageVolPtr vol); int virStorageVolFree (virStorageVolPtr vol); int virStorageVolGetInfo (virStorageVolPtr vol, @@ -1045,6 +1050,7 @@ int virNodeDeviceListCaps (virNodeDevicePtr dev, char * virNodeDeviceGetXMLDesc (virNodeDevicePtr dev, unsigned int flags); +int virNodeDeviceRef (virNodeDevicePtr dev); int virNodeDeviceFree (virNodeDevicePtr dev); /* diff --git a/src/libvirt.c b/src/libvirt.c index ae1a04e3cc..2bb46e4ba2 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -1119,6 +1119,35 @@ virConnectClose(virConnectPtr conn) return (0); } +/** + * virConnectRef: + * @conn: the connection to hold a reference on + * + * Increment the reference count on the connection. For each + * additional call to this method, there shall be a corresponding + * call to virConnectClose to release the reference count, once + * the caller no longer needs the reference to this object. + * + * This method is typically useful for applications where multiple + * threads are using a connection, and it is required that the + * connection remain open until all threads have finished using + * it. ie, each new thread using a connection would increment + * the reference count. + */ +int +virConnectRef(virConnectPtr conn) +{ + if ((!VIR_IS_CONNECT(conn))) { + virLibConnError(NULL, VIR_ERR_INVALID_ARG, __FUNCTION__); + return(-1); + } + virMutexLock(&conn->lock); + DEBUG("conn=%p refs=%d", conn, conn->refs); + conn->refs++; + virMutexUnlock(&conn->lock); + return 0; +} + /* * Not for public use. This function is part of the internal * implementation of driver features in the remote case. @@ -1776,6 +1805,36 @@ virDomainFree(virDomainPtr domain) return(0); } +/** + * virDomainRef: + * @conn: the domain to hold a reference on + * + * Increment the reference count on the domain. For each + * additional call to this method, there shall be a corresponding + * call to virDomainFree to release the reference count, once + * the caller no longer needs the reference to this object. + * + * This method is typically useful for applications where multiple + * threads are using a connection, and it is required that the + * connection remain open until all threads have finished using + * it. ie, each new thread using a domain would increment + * the reference count. + */ +int +virDomainRef(virDomainPtr domain) +{ + if ((!VIR_IS_CONNECTED_DOMAIN(domain))) { + virLibConnError(NULL, VIR_ERR_INVALID_ARG, __FUNCTION__); + return(-1); + } + virMutexLock(&domain->conn->lock); + DEBUG("domain=%p refs=%d", domain, domain->refs); + domain->refs++; + virMutexUnlock(&domain->conn->lock); + return 0; +} + + /** * virDomainSuspend: * @domain: a domain object @@ -4813,6 +4872,35 @@ virNetworkFree(virNetworkPtr network) return(0); } +/** + * virNetworkRef: + * @conn: the network to hold a reference on + * + * Increment the reference count on the network. For each + * additional call to this method, there shall be a corresponding + * call to virNetworkFree to release the reference count, once + * the caller no longer needs the reference to this object. + * + * This method is typically useful for applications where multiple + * threads are using a connection, and it is required that the + * connection remain open until all threads have finished using + * it. ie, each new thread using a network would increment + * the reference count. + */ +int +virNetworkRef(virNetworkPtr network) +{ + if ((!VIR_IS_CONNECTED_NETWORK(network))) { + virLibConnError(NULL, VIR_ERR_INVALID_ARG, __FUNCTION__); + return(-1); + } + virMutexLock(&network->conn->lock); + DEBUG("network=%p refs=%d", network, network->refs); + network->refs++; + virMutexUnlock(&network->conn->lock); + return 0; +} + /** * virNetworkGetName: * @network: a network object @@ -5868,6 +5956,35 @@ virStoragePoolFree(virStoragePoolPtr pool) } +/** + * virStoragePoolRef: + * @conn: the pool to hold a reference on + * + * Increment the reference count on the pool. For each + * additional call to this method, there shall be a corresponding + * call to virStoragePoolFree to release the reference count, once + * the caller no longer needs the reference to this object. + * + * This method is typically useful for applications where multiple + * threads are using a connection, and it is required that the + * connection remain open until all threads have finished using + * it. ie, each new thread using a pool would increment + * the reference count. + */ +int +virStoragePoolRef(virStoragePoolPtr pool) +{ + if ((!VIR_IS_CONNECTED_STORAGE_POOL(pool))) { + virLibConnError(NULL, VIR_ERR_INVALID_ARG, __FUNCTION__); + return(-1); + } + virMutexLock(&pool->conn->lock); + DEBUG("pool=%p refs=%d", pool, pool->refs); + pool->refs++; + virMutexUnlock(&pool->conn->lock); + return 0; +} + /** * virStoragePoolRefresh: * @pool: pointer to storage pool @@ -6620,6 +6737,35 @@ virStorageVolFree(virStorageVolPtr vol) } +/** + * virStorageVolRef: + * @conn: the vol to hold a reference on + * + * Increment the reference count on the vol. For each + * additional call to this method, there shall be a corresponding + * call to virStorageVolFree to release the reference count, once + * the caller no longer needs the reference to this object. + * + * This method is typically useful for applications where multiple + * threads are using a connection, and it is required that the + * connection remain open until all threads have finished using + * it. ie, each new thread using a vol would increment + * the reference count. + */ +int +virStorageVolRef(virStorageVolPtr vol) +{ + if ((!VIR_IS_CONNECTED_STORAGE_VOL(vol))) { + virLibConnError(NULL, VIR_ERR_INVALID_ARG, __FUNCTION__); + return(-1); + } + virMutexLock(&vol->conn->lock); + DEBUG("vol=%p refs=%d", vol, vol->refs); + vol->refs++; + virMutexUnlock(&vol->conn->lock); + return 0; +} + /** * virStorageVolGetInfo: * @vol: pointer to storage volume @@ -7093,6 +7239,36 @@ int virNodeDeviceFree(virNodeDevicePtr dev) } +/** + * virNodeDeviceRef: + * @conn: the dev to hold a reference on + * + * Increment the reference count on the dev. For each + * additional call to this method, there shall be a corresponding + * call to virNodeDeviceFree to release the reference count, once + * the caller no longer needs the reference to this object. + * + * This method is typically useful for applications where multiple + * threads are using a connection, and it is required that the + * connection remain open until all threads have finished using + * it. ie, each new thread using a dev would increment + * the reference count. + */ +int +virNodeDeviceRef(virNodeDevicePtr dev) +{ + if ((!VIR_IS_CONNECTED_NODE_DEVICE(dev))) { + virLibConnError(NULL, VIR_ERR_INVALID_ARG, __FUNCTION__); + return(-1); + } + virMutexLock(&dev->conn->lock); + DEBUG("dev=%p refs=%d", dev, dev->refs); + dev->refs++; + virMutexUnlock(&dev->conn->lock); + return 0; +} + + /* * Domain Event Notification */ @@ -7107,6 +7283,13 @@ int virNodeDeviceFree(virNodeDevicePtr dev) * Adds a Domain Event Callback. * Registering for a domain callback will enable delivery of the events * + * The virDomainPtr object handle passed into the callback upon delivery + * of an event is only valid for the duration of execution of the callback. + * If the callback wishes to keep the domain object after the callback + * returns, it shall take a reference to it, by calling virDomainRef. + * The reference can be released once the object is no longer required + * by calling virDomainFree. + * * Returns 0 on success, -1 on failure */ int diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms index be3fb4f737..0555c9074f 100644 --- a/src/libvirt_public.syms +++ b/src/libvirt_public.syms @@ -236,5 +236,15 @@ LIBVIRT_0.5.0 { } LIBVIRT_0.4.5; -# no new entry point in 0.5.1 +LIBVIRT_0.6.0 { + global: + virConnectRef; + virDomainRef; + virNetworkRef; + virStoragePoolRef; + virStorageVolRef; + virNodeDeviceRef; + +} LIBVIRT_0.5.0; + # .... define new API here using predicted next version number .... -- GitLab