This function must bump refcount of the returned resource because it
just returns the one that was registered with libvirt_connect call,
otherwise it would sefgault if calling code called this function more
than once and the return of the first call would be GCd before the 2nd
call.
---
src/libvirt-php.c | 18 ++++++------------
src/libvirt-php.h | 14 +++++++++-----
2 files changed, 15 insertions(+), 17 deletions(-)
diff --git a/src/libvirt-php.c b/src/libvirt-php.c
index 73466f1..89b17bb 100644
--- a/src/libvirt-php.c
+++ b/src/libvirt-php.c
@@ -2177,13 +2177,8 @@ PHP_FUNCTION(libvirt_connect)
resource_change_counter(INT_RESOURCE_CONNECTION, NULL, conn->conn, 1 TSRMLS_CC);
DPRINTF("%s: Connection to %s established, returning %p\n", PHPFUNC, url,
conn->conn);
-#if PHP_MAJOR_VERSION >= 7
- conn->resource_id = zend_register_resource(conn, le_libvirt_connection);
- ZVAL_RES(return_value, conn->resource_id);
-#else
- ZEND_REGISTER_RESOURCE(return_value, conn, le_libvirt_connection);
- conn->resource_id = Z_LVAL_P(return_value);
-#endif
+ VIRT_REGISTER_RESOURCE(conn, le_libvirt_connection);
+ conn->resource = VIRT_RESOURCE_HANDLE(return_value);
}
/*
@@ -7216,11 +7211,10 @@ PHP_FUNCTION(libvirt_domain_get_connect)
conn = domain->conn;
if (conn->conn == NULL)
RETURN_FALSE;
-#if PHP_MAJOR_VERSION >= 7
- ZVAL_RES(return_value, conn->resource_id);
-#else
- RETURN_RESOURCE(conn->resource_id);
-#endif
+
+ VIRT_RETURN_RESOURCE(conn->resource);
+ /* since we're returning already registered resource, bump refcount */
+ Z_ADDREF_P(return_value);
}
/*
diff --git a/src/libvirt-php.h b/src/libvirt-php.h
index 0422661..ed6a8bc 100644
--- a/src/libvirt-php.h
+++ b/src/libvirt-php.h
@@ -122,6 +122,7 @@ typedef uint64_t arch_uint;
#if PHP_MAJOR_VERSION >= 7
typedef size_t strsize_t;
typedef zend_resource virt_resource;
+typedef virt_resource *virt_resource_handle;
#define VIRT_RETURN_RESOURCE(_resource) \
RETVAL_RES(_resource)
@@ -135,6 +136,9 @@ typedef zend_resource virt_resource;
add_next_index_zval(return_value, &zret); \
} while(0)
+#define VIRT_RESOURCE_HANDLE(_resource) \
+ Z_RES_P(_resource)
+
#define VIRT_FETCH_RESOURCE(_state, _type, _zval, _name, _le) \
if ((_state = (_type)zend_fetch_resource(Z_RES_P(*_zval), _name, _le)) == NULL) { \
RETURN_FALSE; \
@@ -179,6 +183,7 @@ typedef int strsize_t;
typedef long zend_long;
typedef unsigned long zend_ulong;
typedef zend_rsrc_list_entry virt_resource;
+typedef long virt_resource_handle;
#define VIRT_RETURN_RESOURCE(_resource) \
RETVAL_RESOURCE((long) _resource)
@@ -193,6 +198,9 @@ typedef zend_rsrc_list_entry virt_resource;
add_next_index_zval(return_value, zret); \
} while(0)
+#define VIRT_RESOURCE_HANDLE(_resource) \
+ Z_LVAL_P(_resource)
+
#define VIRT_FETCH_RESOURCE(_state, _type, _zval, _name, _le) \
ZEND_FETCH_RESOURCE(_state, _type, _zval, -1, _name, _le);
@@ -298,11 +306,7 @@ typedef struct tVMNetwork {
/* Libvirt-php types */
typedef struct _php_libvirt_connection {
virConnectPtr conn;
-#if PHP_MAJOR_VERSION >= 7
- zend_resource *resource_id;
-#else
- long resource_id;
-#endif
+ virt_resource_handle resource;
} php_libvirt_connection;
typedef struct _php_libvirt_stream {
--
2.13.0