Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Memory leak in Python target fixed #246

Merged
merged 13 commits into from
Jul 11, 2023
17 changes: 9 additions & 8 deletions core/lf_token.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,23 +130,24 @@ lf_token_t* lf_writable_copy(lf_port_base_t* port) {

////////////////////////////////////////////////////////////////////
//// Internal functions.

void _lf_free_token_value(lf_token_t* token) {
if (token->value != NULL) {
// Count frees to issue a warning if this is never freed.
_lf_count_payload_allocations--;
// Free the value field (the payload).
// First check whether the value field is garbage collected (e.g. in the
// Python target), in which case the payload should not be freed.
#ifndef _LF_GARBAGE_COLLECTED
LF_PRINT_DEBUG("_lf_free_token_value: Freeing allocated memory for payload (token value): %p",
token->value);
if (token->type->destructor == NULL) {
free(token->value);
} else {
token->value);
// First check the token's destructor field and invoke it if it is not NULL.
if (token->type->destructor != NULL) {
token->type->destructor(token->value);
}
// If Python Target is not enabled and destructor is NULL
// Token values should be freed
else {
#ifndef _PYTHON_TARGET_ENABLED
free(token->value);
#endif
}
token->value = NULL;
}
}
Expand Down
1 change: 1 addition & 0 deletions python/include/python_port.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,4 +98,5 @@ typedef struct {
FEDERATED_CAPSULE_EXTENSION
} generic_port_capsule_struct;

void python_count_decrement(void* py_object);
#endif
28 changes: 21 additions & 7 deletions python/lib/python_port.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,21 @@ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "python_port.h"
#include "reactor.h"
#include "api/api.h"
#include "api/set.h"

PyTypeObject py_port_capsule_t;

//////////// destructor Function(s) /////////////
/**
* Decrease the reference count of PyObject. When the reference count hits zero,
* Python can free its memory.
* @param py_object A PyObject with count 1 or greater.
*/
void python_count_decrement(void* py_object) {
Py_XDECREF((PyObject*)py_object);
}

//////////// set Function(s) /////////////
/**
* Set the value and is_present field of self which is of type
Expand Down Expand Up @@ -68,7 +80,7 @@ PyTypeObject py_port_capsule_t;
* @param args contains:
* - val: The value to insert into the port struct.
*/
PyObject* py_port_set(PyObject *self, PyObject *args) {
PyObject* py_port_set(PyObject* self, PyObject* args) {
generic_port_capsule_struct* p = (generic_port_capsule_struct*)self;
PyObject* val = NULL;

Expand All @@ -85,13 +97,15 @@ PyObject* py_port_set(PyObject *self, PyObject *args) {
}

if (val) {
LF_PRINT_DEBUG("Setting value %p.", val);
Py_XDECREF(port->value);
Py_INCREF(val);
// Call the core lib API to set the port
_LF_SET(port, val);

LF_PRINT_DEBUG("Setting value %p with reference count %d.", val, (int) Py_REFCNT(val));
//Py_INCREF(val);
//python_count_decrement(port->value);

lf_token_t* token = lf_new_token((void*)port, val, 1);
lf_set_destructor(port, python_count_decrement);
edwardalee marked this conversation as resolved.
Show resolved Hide resolved
lf_set_token(port, token);
Py_INCREF(val);
petervdonovan marked this conversation as resolved.
Show resolved Hide resolved

// Also set the values for the port capsule.
p->value = val;
p->is_present = true;
Expand Down
Loading