Commit 8400bc24 authored by gsamain's avatar gsamain Committed by Xavier Thompson

Change strategy for outer variables: lock them at the beginning, unlock at the end

parent 108d4195
...@@ -319,7 +319,7 @@ class ExprNode(Node): ...@@ -319,7 +319,7 @@ class ExprNode(Node):
result_is_used = True result_is_used = True
is_numpy_attribute = False is_numpy_attribute = False
tracked_state = None tracked_state = None
was_locked = True was_locked = False
# The Analyse Expressions phase for expressions is split # The Analyse Expressions phase for expressions is split
# into two sub-phases: # into two sub-phases:
...@@ -758,6 +758,8 @@ class ExprNode(Node): ...@@ -758,6 +758,8 @@ class ExprNode(Node):
self.tracked_state = env.lookup_tracked(self.entry) self.tracked_state = env.lookup_tracked(self.entry)
if self.tracked_state is None: if self.tracked_state is None:
self.tracked_state = env.declare_tracked(self.entry) self.tracked_state = env.declare_tracked(self.entry)
if self.is_autolock() and self.entry.is_variable:
env.declare_autolocked(self)
self.was_locked = self.tracked_state.was_locked self.was_locked = self.tracked_state.was_locked
self.tracked_state.was_locked = True self.tracked_state.was_locked = True
...@@ -802,7 +804,8 @@ class ExprNode(Node): ...@@ -802,7 +804,8 @@ class ExprNode(Node):
if not self.tracked_state: if not self.tracked_state:
self.get_tracked_state(env) self.get_tracked_state(env)
if self.is_autolock() and is_top_lhs: if self.is_autolock() and is_top_lhs:
env.declare_autolocked(self) #env.declare_autolocked(self)
self.tracked_as_lhs = True
if is_dereferenced and self.tracked_state: if is_dereferenced and self.tracked_state:
if not self.is_lhs_locked(env): if not self.is_lhs_locked(env):
if self.is_checklock(): if self.is_checklock():
...@@ -2416,12 +2419,6 @@ class NameNode(AtomicExprNode): ...@@ -2416,12 +2419,6 @@ class NameNode(AtomicExprNode):
elif entry.type.is_cyp_class: elif entry.type.is_cyp_class:
code.put_cygotref(self.result()) code.put_cygotref(self.result())
if not self.was_locked and self.is_autolock():
tracked_state = self.tracked_state
if tracked_state.needs_wlock:
code.putln("Cy_WLOCK(%s);" % self.result())
elif tracked_state.needs_rlock:
code.putln("Cy_RLOCK(%s);" % self.result())
#pass #pass
# code.putln(entry.cname) # code.putln(entry.cname)
elif entry.is_local or entry.in_closure or entry.from_closure or entry.type.is_memoryviewslice: elif entry.is_local or entry.in_closure or entry.from_closure or entry.type.is_memoryviewslice:
...@@ -7560,12 +7557,6 @@ class AttributeNode(ExprNode): ...@@ -7560,12 +7557,6 @@ class AttributeNode(ExprNode):
'"Memoryview is not initialized");' '"Memoryview is not initialized");'
'%s' '%s'
'}' % (self.result(), code.error_goto(self.pos))) '}' % (self.result(), code.error_goto(self.pos)))
elif self.is_autolock():
if not self.was_locked:
if self.tracked_state.needs_wlock:
code.putln("Cy_WLOCK(%s);" % self.result())
elif self.tracked_state.needs_rlock:
code.putln("Cy_RLOCK(%s);" % self.result())
else: else:
# result_code contains what is needed, but we may need to insert # result_code contains what is needed, but we may need to insert
# a check and raise an exception # a check and raise an exception
...@@ -7580,9 +7571,6 @@ class AttributeNode(ExprNode): ...@@ -7580,9 +7571,6 @@ class AttributeNode(ExprNode):
# mirror condition for putting the memview incref here: # mirror condition for putting the memview incref here:
code.put_xdecref_clear(self.result(), self.type, have_gil=True) code.put_xdecref_clear(self.result(), self.type, have_gil=True)
else: else:
if self.is_temp and self.type.is_cyp_class and self.is_autolock()\
and self.tracked_state and (tracked_state.needs_rlock or tracked_state.needs_wlock):
code.putln("Cy_UNLOCK(%s);" % self.result())
ExprNode.generate_disposal_code(self, code) ExprNode.generate_disposal_code(self, code)
def generate_assignment_code(self, rhs, code, overloaded_assignment=False, def generate_assignment_code(self, rhs, code, overloaded_assignment=False,
......
...@@ -2045,6 +2045,15 @@ class FuncDefNode(StatNode, BlockNode): ...@@ -2045,6 +2045,15 @@ class FuncDefNode(StatNode, BlockNode):
code.put_release_ensured_gil() code.put_release_ensured_gil()
code.funcstate.gil_owned = False code.funcstate.gil_owned = False
for node in lenv.autolocked_nodes:
if node.entry.is_variable and not node.entry.is_local and (node.tracked_state.needs_wlock or node.tracked_state.needs_rlock):
node_result = node.result()
code.putln("if (%s != NULL)" % node_result)
if node.needs_wlock():
code.putln(" Cy_WLOCK(%s);" % node_result)
elif node.needs_rlock():
code.putln(" Cy_RLOCK(%s);" % node_result)
# ------------------------- # -------------------------
# ----- Function body ----- # ----- Function body -----
# ------------------------- # -------------------------
...@@ -2214,7 +2223,7 @@ class FuncDefNode(StatNode, BlockNode): ...@@ -2214,7 +2223,7 @@ class FuncDefNode(StatNode, BlockNode):
# which leads to a dangling lock on the previous reference # which leads to a dangling lock on the previous reference
# (and attempt to unlock a non-locked ref). # (and attempt to unlock a non-locked ref).
if not node.was_locked and (node.tracked_state.needs_wlock or node.tracked_state.needs_rlock): if not node.get_was_locked() and (node.tracked_state.needs_wlock or node.tracked_state.needs_rlock):
code.putln("Cy_UNLOCK(%s);" % node.result()) code.putln("Cy_UNLOCK(%s);" % node.result())
for entry in lenv.var_entries: for entry in lenv.var_entries:
......
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