From 72fd96164cb13013565a6145078bb64456b47cec Mon Sep 17 00:00:00 2001 From: Stefan Behnel Date: Mon, 27 Dec 2010 10:05:37 +0100 Subject: [PATCH] always INCREF Python arguments in 'with gil' C functions as we cannot know who owns them --- Cython/Compiler/Nodes.py | 4 ++-- tests/run/owned_arg_refs.pyx | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/Cython/Compiler/Nodes.py b/Cython/Compiler/Nodes.py index 4a0b65bb..41b55d6c 100644 --- a/Cython/Compiler/Nodes.py +++ b/Cython/Compiler/Nodes.py @@ -1353,7 +1353,7 @@ class FuncDefNode(StatNode, BlockNode): # incref it to properly keep track of refcounts. for entry in lenv.arg_entries: if entry.type.is_pyobject: - if entry.assignments and not entry.in_closure: + if (acquire_gil or entry.assignments) and not entry.in_closure: code.put_var_incref(entry) # ----- Initialise local variables for entry in lenv.var_entries: @@ -1463,7 +1463,7 @@ class FuncDefNode(StatNode, BlockNode): if entry.type.is_pyobject: if entry.in_closure: code.put_var_giveref(entry) - elif entry.assignments: + elif acquire_gil or entry.assignments: code.put_var_decref(entry) if self.needs_closure: code.put_decref(Naming.cur_scope_cname, lenv.scope_class.type) diff --git a/tests/run/owned_arg_refs.pyx b/tests/run/owned_arg_refs.pyx index 5bf84d76..69058ada 100644 --- a/tests/run/owned_arg_refs.pyx +++ b/tests/run/owned_arg_refs.pyx @@ -15,6 +15,24 @@ def test_ext_type_attr(): owner.x = ''.join("abc%d" % 5) # non-interned object return call_me_with_owner(owner, owner.x) + +cdef void call_me_without_gil(Owner owner, x) with gil: + owner.x = "def" # overwrite external reference + print x # crashes if x is not owned by function or caller + +def test_ext_type_attr_nogil(): + """ + >>> test_ext_type_attr_nogil() + abc5 + """ + owner = Owner() + owner.x = ''.join("abc%d" % 5) # non-interned object + with nogil: + call_me_without_gil(owner, owner.x) + + +# the following isn't dangerous as long as index access uses temps + cdef call_me_with_list(list l, x): l[:] = [(1,2), (3,4)] # overwrite external reference return x # crashes if x is not owned by function or caller -- 2.26.2