summaryrefslogtreecommitdiff
path: root/gi/pygi-boxed.c
diff options
context:
space:
mode:
authorChristoph Reiter <reiter.christoph@gmail.com>2018-02-13 23:26:21 +0100
committerChristoph Reiter <reiter.christoph@gmail.com>2018-02-13 22:32:45 +0000
commita506d5e3c64321c43a4ce7c2a72ca8d36e985999 (patch)
tree60ab2deba5c16cf4a384523148417fd326819535 /gi/pygi-boxed.c
parent700c785367975995d24a8ffd00b2aa028ccf77e8 (diff)
downloadpygobject-a506d5e3c64321c43a4ce7c2a72ca8d36e985999.tar.gz
Revert "Revert "Refactor boxed wrapper memory management strategy""
This reverts commit daefdfa3e4dc97b4ae38250358d722f09764cc9b.
Diffstat (limited to 'gi/pygi-boxed.c')
-rw-r--r--gi/pygi-boxed.c32
1 files changed, 25 insertions, 7 deletions
diff --git a/gi/pygi-boxed.c b/gi/pygi-boxed.c
index fa690bb3..e9014f20 100644
--- a/gi/pygi-boxed.c
+++ b/gi/pygi-boxed.c
@@ -113,7 +113,7 @@ _boxed_new (PyTypeObject *type,
goto out;
}
- self = (PyGIBoxed *) _pygi_boxed_new (type, boxed, TRUE, size);
+ self = (PyGIBoxed *) _pygi_boxed_new (type, boxed, FALSE, size);
if (self == NULL) {
g_slice_free1 (size, boxed);
goto out;
@@ -149,30 +149,48 @@ _boxed_init (PyObject *self,
PYGLIB_DEFINE_TYPE("gi.Boxed", PyGIBoxed_Type, PyGIBoxed);
PyObject *
-_pygi_boxed_new (PyTypeObject *type,
+_pygi_boxed_new (PyTypeObject *pytype,
gpointer boxed,
- gboolean free_on_dealloc,
+ gboolean copy_boxed,
gsize allocated_slice)
{
PyGIBoxed *self;
+ GType gtype;
if (!boxed) {
Py_RETURN_NONE;
}
- if (!PyType_IsSubtype (type, &PyGIBoxed_Type)) {
+ if (!PyType_IsSubtype (pytype, &PyGIBoxed_Type)) {
PyErr_SetString (PyExc_TypeError, "must be a subtype of gi.Boxed");
return NULL;
}
- self = (PyGIBoxed *) type->tp_alloc (type, 0);
+ gtype = pyg_type_from_object ((PyObject *)pytype);
+
+ /* Boxed objects with slice allocation means they come from caller allocated
+ * out arguments. In this case copy_boxed does not make sense because we
+ * already own the slice allocated memory and we should be receiving full
+ * ownership transfer. */
+ if (copy_boxed) {
+ g_assert (allocated_slice == 0);
+ boxed = g_boxed_copy (gtype, boxed);
+ }
+
+ self = (PyGIBoxed *) pytype->tp_alloc (pytype, 0);
if (self == NULL) {
return NULL;
}
- ( (PyGBoxed *) self)->gtype = pyg_type_from_object ( (PyObject *) type);
- ( (PyGBoxed *) self)->free_on_dealloc = free_on_dealloc;
+ /* We always free on dealloc because we always own the memory due to:
+ * 1) copy_boxed == TRUE
+ * 2) allocated_slice > 0
+ * 3) otherwise the mode is assumed "transfer everything".
+ */
+ ((PyGBoxed *)self)->free_on_dealloc = TRUE;
+ ((PyGBoxed *)self)->gtype = gtype;
pyg_boxed_set_ptr (self, boxed);
+
if (allocated_slice > 0) {
self->size = allocated_slice;
self->slice_allocated = TRUE;