From 68adfdb2958539f18cea02f08ae9919379fa7dba Mon Sep 17 00:00:00 2001 From: Guido Trotter <ultrotter@google.com> Date: Tue, 8 Jul 2008 16:32:07 +0000 Subject: [PATCH] Processor: Acquire locks before executing an LU If we're running in a "new style" LU we may need some locks, as required by the ExpandNames function, to be able to run. We'll walk up the lock levels present in the needed_locks dictionary and acquire them, then run the actual LU. LUs can release some or all the acquired locks, if they want, before terminating, provided they update their needed_locks dictionary appropriately, so that we know not to release a level if they have already done so. Reviewed-by: iustinp --- lib/mcpu.py | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/lib/mcpu.py b/lib/mcpu.py index 0d9e7037b..4bdfb4671 100644 --- a/lib/mcpu.py +++ b/lib/mcpu.py @@ -123,6 +123,29 @@ class Processor(object): return result + def _LockAndExecLU(self, lu, level): + """Execute a Logical Unit, with the needed locks. + + This is a recursive function that starts locking the given level, and + proceeds up, till there are no more locks to acquire. Then it executes the + given LU and its opcodes. + + """ + if level in lu.needed_locks: + # This is always safe to do, as we can't acquire more/less locks than + # what was requested. + lu.needed_locks[level] = self.context.glm.acquire(level, + lu.needed_locks[level]) + try: + result = self._LockAndExecLU(lu, level + 1) + finally: + if lu.needed_locks[level]: + self.context.glm.release(level) + else: + result = self._ExecLU(lu) + + return result + def ExecOpCode(self, op): """Execute an opcode. @@ -151,7 +174,8 @@ class Processor(object): self.exclusive_BGL = lu_class.REQ_BGL lu = lu_class(self, op, self.context, sstore) lu.ExpandNames() - result = self._ExecLU(lu) + assert lu.needed_locks is not None, "needed_locks not set by LU" + result = self._LockAndExecLU(lu, locking.LEVEL_NODE) finally: self.context.glm.release(locking.LEVEL_CLUSTER) self.exclusive_BGL = False -- GitLab