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>'
|
__copyright__ = '2011, Kovid Goyal <kovid@kovidgoyal.net>'
|
||||||
__docformat__ = 'restructuredtext en'
|
__docformat__ = 'restructuredtext en'
|
||||||
|
|
||||||
|
import traceback, sys
|
||||||
from threading import Lock, Condition, current_thread, RLock
|
from threading import Lock, Condition, current_thread, RLock
|
||||||
from functools import partial
|
from functools import partial
|
||||||
from collections import Counter
|
from collections import Counter
|
||||||
|
from calibre.utils.config_base import tweaks
|
||||||
|
|
||||||
class LockingError(RuntimeError):
|
class LockingError(RuntimeError):
|
||||||
pass
|
|
||||||
|
def __init__(self, msg, extra=None):
|
||||||
|
RuntimeError.__init__(self, msg)
|
||||||
|
self.locking_debug_msg = extra
|
||||||
|
|
||||||
def create_locks():
|
def create_locks():
|
||||||
'''
|
'''
|
||||||
@ -37,7 +42,8 @@ def create_locks():
|
|||||||
the possibility of deadlocking in this scenario).
|
the possibility of deadlocking in this scenario).
|
||||||
'''
|
'''
|
||||||
l = SHLock()
|
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): # {{{
|
class SHLock(object): # {{{
|
||||||
'''
|
'''
|
||||||
@ -217,6 +223,31 @@ class RWLockWrapper(object):
|
|||||||
def owns_lock(self):
|
def owns_lock(self):
|
||||||
return self._shlock.owns_lock()
|
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):
|
class RecordLock(object):
|
||||||
|
|
||||||
'''
|
'''
|
||||||
|
@ -113,6 +113,8 @@ class MainWindow(QMainWindow):
|
|||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
traceback.print_exception(type, value, tb, file=sio)
|
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()
|
fe = sio.getvalue()
|
||||||
prints(fe, file=sys.stderr)
|
prints(fe, file=sys.stderr)
|
||||||
msg = '<b>%s</b>:'%type.__name__ + unicode(str(value), 'utf8', 'replace')
|
msg = '<b>%s</b>:'%type.__name__ + unicode(str(value), 'utf8', 'replace')
|
||||||
|
Loading…
x
Reference in New Issue
Block a user