Commit 72fd9616 authored by Stefan Behnel's avatar Stefan Behnel

always INCREF Python arguments in 'with gil' C functions as we cannot know who owns them

parent 30504bdb
...@@ -1353,7 +1353,7 @@ class FuncDefNode(StatNode, BlockNode): ...@@ -1353,7 +1353,7 @@ class FuncDefNode(StatNode, BlockNode):
# incref it to properly keep track of refcounts. # incref it to properly keep track of refcounts.
for entry in lenv.arg_entries: for entry in lenv.arg_entries:
if entry.type.is_pyobject: 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) code.put_var_incref(entry)
# ----- Initialise local variables # ----- Initialise local variables
for entry in lenv.var_entries: for entry in lenv.var_entries:
...@@ -1463,7 +1463,7 @@ class FuncDefNode(StatNode, BlockNode): ...@@ -1463,7 +1463,7 @@ class FuncDefNode(StatNode, BlockNode):
if entry.type.is_pyobject: if entry.type.is_pyobject:
if entry.in_closure: if entry.in_closure:
code.put_var_giveref(entry) code.put_var_giveref(entry)
elif entry.assignments: elif acquire_gil or entry.assignments:
code.put_var_decref(entry) code.put_var_decref(entry)
if self.needs_closure: if self.needs_closure:
code.put_decref(Naming.cur_scope_cname, lenv.scope_class.type) code.put_decref(Naming.cur_scope_cname, lenv.scope_class.type)
......
...@@ -15,6 +15,24 @@ def test_ext_type_attr(): ...@@ -15,6 +15,24 @@ def test_ext_type_attr():
owner.x = ''.join("abc%d" % 5) # non-interned object owner.x = ''.join("abc%d" % 5) # non-interned object
return call_me_with_owner(owner, owner.x) 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): cdef call_me_with_list(list l, x):
l[:] = [(1,2), (3,4)] # overwrite external reference l[:] = [(1,2), (3,4)] # overwrite external reference
return x # crashes if x is not owned by function or caller return x # crashes if x is not owned by function or caller
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment