mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
Add a tweak to debug newdb locking issues
This commit is contained in:
parent
2fbcd61fb4
commit
e459dee9c6
@ -7,12 +7,17 @@ __license__ = 'GPL v3'
|
||||
__copyright__ = '2011, Kovid Goyal <kovid@kovidgoyal.net>'
|
||||
__docformat__ = 'restructuredtext en'
|
||||
|
||||
import traceback, sys
|
||||
from threading import Lock, Condition, current_thread, RLock
|
||||
from functools import partial
|
||||
from collections import Counter
|
||||
from calibre.utils.config_base import tweaks
|
||||
|
||||
class LockingError(RuntimeError):
|
||||
pass
|
||||
|
||||
def __init__(self, msg, extra=None):
|
||||
RuntimeError.__init__(self, msg)
|
||||
self.locking_debug_msg = extra
|
||||
|
||||
def create_locks():
|
||||
'''
|
||||
@ -37,7 +42,8 @@ def create_locks():
|
||||
the possibility of deadlocking in this scenario).
|
||||
'''
|
||||
l = SHLock()
|
||||
return RWLockWrapper(l), RWLockWrapper(l, is_shared=False)
|
||||
wrapper = DebugRWLockWrapper if tweaks.get('newdb_debug_locking', False) else RWLockWrapper
|
||||
return wrapper(l), wrapper(l, is_shared=False)
|
||||
|
||||
class SHLock(object): # {{{
|
||||
'''
|
||||
@ -217,6 +223,31 @@ class RWLockWrapper(object):
|
||||
def owns_lock(self):
|
||||
return self._shlock.owns_lock()
|
||||
|
||||
class DebugRWLockWrapper(RWLockWrapper):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
RWLockWrapper.__init__(self, *args, **kwargs)
|
||||
self._last_acquire = ()
|
||||
|
||||
def __enter__(self):
|
||||
try:
|
||||
RWLockWrapper.__enter__(self)
|
||||
except LockingError as e:
|
||||
if self._last_acquire is None:
|
||||
raise
|
||||
et, ei, tb = sys.exc_info()
|
||||
raise LockingError, LockingError(e.message, extra='Last successful call to acquire():\n' + ''.join(self._last_acquire)), tb
|
||||
self._last_acquire = traceback.format_stack()
|
||||
|
||||
def release(self):
|
||||
try:
|
||||
RWLockWrapper.release(self)
|
||||
except LockingError as e:
|
||||
if self._last_acquire is None:
|
||||
raise
|
||||
et, ei, tb = sys.exc_info()
|
||||
raise LockingError, LockingError(e.message, extra='Last successful call to acquire():\n' + ''.join(self._last_acquire)), tb
|
||||
|
||||
class RecordLock(object):
|
||||
|
||||
'''
|
||||
|
@ -113,6 +113,8 @@ class MainWindow(QMainWindow):
|
||||
except:
|
||||
pass
|
||||
traceback.print_exception(type, value, tb, file=sio)
|
||||
if getattr(value, 'locking_debug_msg', None):
|
||||
prints(value.locking_debug_msg, file=sio)
|
||||
fe = sio.getvalue()
|
||||
prints(fe, file=sys.stderr)
|
||||
msg = '<b>%s</b>:'%type.__name__ + unicode(str(value), 'utf8', 'replace')
|
||||
|
Loading…
x
Reference in New Issue
Block a user