Edited lockhandler to pre-determine an object's superuser-status instead of re-acquiring it every lock check. This caused a surprisingly large overhead considering how often locks are checked for various reasons.

This commit is contained in:
Griatch 2012-04-28 15:26:52 +02:00
parent 2dba8ad547
commit e92c9ac93e
2 changed files with 22 additions and 16 deletions

View file

@ -1938,7 +1938,7 @@ class CmdScript(MuxCommand):
key = "@script" key = "@script"
aliases = "@addscript" aliases = "@addscript"
locks = "cmd:perm(script) or perm(Wizards)" locks = "cmd:perm(script) or perm(Builders)"
help_category = "Building" help_category = "Building"
def func(self): def func(self):

View file

@ -167,10 +167,13 @@ class LockHandler(object):
self.log_obj = None self.log_obj = None
self.no_errors = True self.no_errors = True
self.reset_flag = False self.reset_flag = False
self._cache_locks(self.obj.lock_storage) self._cache_locks(self.obj.lock_storage)
# we handle most bypass checks already here. We need to grant access to superusers and
# to protocol instances where the superuser status cannot be determined (can happen at
# some rare cases during login).
self.lock_bypass = ((hasattr(obj, "is_superuser") and obj.is_superuser)
or (hasattr(obj, "player") and hasattr(obj.player, "is_superuser") and obj.player.is_superuser)
or (hasattr(obj, "get_player") and (not obj.get_player() or obj.get_player().is_superuser)))
def __str__(self): def __str__(self):
return ";".join(self.locks[key][2] for key in sorted(self.locks)) return ";".join(self.locks[key][2] for key in sorted(self.locks))
@ -343,13 +346,12 @@ class LockHandler(object):
self._cache_locks(self.obj.lock_storage) self._cache_locks(self.obj.lock_storage)
self.reset_flag = False self.reset_flag = False
if (not no_superuser_bypass # check if the lock should be bypassed (e.g. superuser status)
and ((hasattr(accessing_obj, 'is_superuser') and accessing_obj.is_superuser) try:
or (hasattr(accessing_obj, 'player') and hasattr(accessing_obj.player, 'is_superuser') and accessing_obj.player.is_superuser) if accessing_obj.locks.lock_bypass and not no_superuser_bypass:
or (hasattr(accessing_obj, 'get_player') and (not accessing_obj.get_player() or accessing_obj.get_player().is_superuser)))): return True
# we grant access to superusers and also to protocol instances that not yet has any player assigned to them (the except AttributeError:
# latter is a safety feature since superuser cannot be authenticated at some point during the connection). pass
return True
if access_type in self.locks: if access_type in self.locks:
# we have a lock, test it. # we have a lock, test it.
@ -362,17 +364,21 @@ class LockHandler(object):
else: else:
return default return default
def check_lockstring(self, accessing_obj, lockstring): def check_lockstring(self, accessing_obj, lockstring, no_superuser_bypass=False):
""" """
Do a direct check against a lockstring ('atype:func()..'), without any Do a direct check against a lockstring ('atype:func()..'), without any
intermediary storage on the accessed object (this can be left intermediary storage on the accessed object (this can be left
to None if the lock functions called don't access it). atype can also be to None if the lock functions called don't access it). atype can also be
put to a dummy value since no lock selection is made. put to a dummy value since no lock selection is made.
""" """
if ((hasattr(accessing_obj, 'is_superuser') and accessing_obj.is_superuser) try:
or (hasattr(accessing_obj, 'player') and hasattr(accessing_obj.player, 'is_superuser') and accessing_obj.player.is_superuser) if accessing_obj.locks.lock_bypass and not no_superuser_bypass:
or (hasattr(accessing_obj, 'get_player') and (accessing_obj.get_player()==None or accessing_obj.get_player().is_superuser))): return True
return True except AttributeError:
if no_superuser_bypass and ((hasattr(accessing_obj, 'is_superuser') and accessing_obj.is_superuser)
or (hasattr(accessing_obj, 'player') and hasattr(accessing_obj.player, 'is_superuser') and accessing_obj.player.is_superuser)
or (hasattr(accessing_obj, 'get_player') and (accessing_obj.get_player()==None or accessing_obj.get_player().is_superuser))):
return True
locks = self. _parse_lockstring(lockstring) locks = self. _parse_lockstring(lockstring)
for access_type in locks: for access_type in locks: