From: Stefan Behnel Date: Mon, 27 Dec 2010 09:05:37 +0000 (+0100) Subject: always INCREF Python arguments in 'with gil' C functions as we cannot know who owns... X-Git-Tag: 0.14.1rc0~13^2~5 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=72fd96164cb13013565a6145078bb64456b47cec;p=cython.git always INCREF Python arguments in 'with gil' C functions as we cannot know who owns them --- 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