@@ -46,28 +46,40 @@ static inline bool is_set(const char *arg)
return !(is_all(arg) || is_no_arg(arg));
}
-static inline void no_free()
+static inline void no_free(void *ptr)
{
}
#define NO_FREE no_free
+static inline void no_destroy(void *ptr)
+{
+}
+
+#define NO_DESTROY no_destroy
+
#define STR(x) #x
#define MAKE_TYPE_STR(x) STR(trace.x)
#define MAKE_DIC_STR(x) STR(libtrace x object)
+typedef struct {
+ PyObject_HEAD
+ bool destroy;
+} PyFtrace_Object_HEAD;
+
#define C_OBJECT_WRAPPER_DECLARE(c_type, py_type) \
typedef struct { \
PyObject_HEAD \
+ bool destroy; \
struct c_type *ptrObj; \
} py_type; \
PyObject *py_type##_New(struct c_type *c_ptr); \
bool py_type##TypeInit(); \
bool py_type##_Check(PyObject *obj); \
-#define C_OBJECT_WRAPPER(c_type, py_type, ptr_free) \
+#define C_OBJECT_WRAPPER(c_type, py_type, obj_destroy, ptr_free) \
static PyTypeObject py_type##Type = { \
PyVarObject_HEAD_INIT(NULL, 0) MAKE_TYPE_STR(c_type) \
}; \
@@ -76,6 +88,7 @@ PyObject *py_type##_New(struct c_type *c_ptr) \
py_type *newObject; \
newObject = PyObject_New(py_type, &py_type##Type); \
newObject->ptrObj = c_ptr; \
+ newObject->destroy = true; \
return (PyObject *) newObject; \
} \
static int py_type##_init(py_type *self, PyObject *args, PyObject *kwargs) \
@@ -85,6 +98,8 @@ static int py_type##_init(py_type *self, PyObject *args, PyObject *kwargs) \
} \
static void py_type##_dealloc(py_type *self) \
{ \
+ if (self->destroy) \
+ obj_destroy(self->ptrObj); \
ptr_free(self->ptrObj); \
Py_TYPE(self)->tp_free(self); \
} \
@@ -536,6 +536,26 @@ PyObject *PyFtrace_dir(PyObject *self)
return PyUnicode_FromString(tracefs_tracing_dir());
}
+PyObject *PyFtrace_detach(PyObject *self, PyObject *args, PyObject *kwargs)
+{
+ static char *kwlist[] = {"object", NULL};
+ PyFtrace_Object_HEAD *obj_head;
+ PyObject *py_obj = NULL;
+
+ if (!PyArg_ParseTupleAndKeywords(args,
+ kwargs,
+ "O",
+ kwlist,
+ &py_obj)) {
+ return false;
+ }
+
+ obj_head = (PyFtrace_Object_HEAD *)py_obj;
+ obj_head->destroy = false;
+
+ Py_RETURN_NONE;
+}
+
static char aname_pool[] =
"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
@@ -46,6 +46,8 @@ PyObject *PyTep_get_event(PyTep *self, PyObject *args,
PyObject *PyFtrace_dir(PyObject *self);
+PyObject *PyFtrace_detach(PyObject *self, PyObject *args, PyObject *kwargs);
+
PyObject *PyFtrace_create_instance(PyObject *self, PyObject *args,
PyObject *kwargs);
@@ -25,7 +25,7 @@ static PyMethodDef PyTepRecord_methods[] = {
{NULL}
};
-C_OBJECT_WRAPPER(tep_record, PyTepRecord, NO_FREE)
+C_OBJECT_WRAPPER(tep_record, PyTepRecord, NO_DESTROY, NO_FREE)
static PyMethodDef PyTepEvent_methods[] = {
{"name",
@@ -55,7 +55,7 @@ static PyMethodDef PyTepEvent_methods[] = {
{NULL}
};
-C_OBJECT_WRAPPER(tep_event, PyTepEvent, NO_FREE)
+C_OBJECT_WRAPPER(tep_event, PyTepEvent, NO_DESTROY, NO_FREE)
static PyMethodDef PyTep_methods[] = {
{"init_local",
@@ -71,7 +71,7 @@ static PyMethodDef PyTep_methods[] = {
{NULL}
};
-C_OBJECT_WRAPPER(tep_handle, PyTep, tep_free)
+C_OBJECT_WRAPPER(tep_handle, PyTep, NO_DESTROY, tep_free)
static PyMethodDef ftracepy_methods[] = {
{"dir",
@@ -79,6 +79,11 @@ static PyMethodDef ftracepy_methods[] = {
METH_NOARGS,
"Get the absolute path to the tracefs directory."
},
+ {"detach",
+ (PyCFunction) PyFtrace_detach,
+ METH_VARARGS | METH_KEYWORDS,
+ "Detach object from the \'ftracepy\' module."
+ },
{"create_instance",
(PyCFunction) PyFtrace_create_instance,
METH_VARARGS | METH_KEYWORDS,
libtracefs distinguishes between freeing the resources managed by an object and the freeing of object itself. One can take tracefs_instance_destroy() and tracefs_instance_free() as example. The user can call tracefs_instance_free() without calling tracefs_instance_destroy(). In this case no memory will leak, but the instance will continue to exist after the program exits (will be 'detached'). Here we add mechanisms that will make possible to detach object from the ftracepy module. Signed-off-by: Yordan Karadzhov (VMware) <y.karadz@gmail.com> --- src/common.h | 19 +++++++++++++++++-- src/ftracepy-utils.c | 20 ++++++++++++++++++++ src/ftracepy-utils.h | 2 ++ src/ftracepy.c | 11 ++++++++--- 4 files changed, 47 insertions(+), 5 deletions(-)