Fix locking thread safe log objects' exception()

Also fix the default stream ignoring the stream parameter to its
constructor.

Change RLock to Lock for better performance, since locking recursion is
not needed
This commit is contained in:
Kovid Goyal 2015-06-02 14:11:16 +05:30
parent 1b745365f4
commit 547ebe941b

View File

@ -12,18 +12,17 @@ ERROR = 3
import sys, traceback, cStringIO import sys, traceback, cStringIO
from functools import partial from functools import partial
from threading import RLock from threading import Lock
from calibre import isbytestring, force_unicode, as_unicode from calibre import isbytestring, force_unicode, as_unicode, prints
class Stream(object): class Stream(object):
def __init__(self, stream=None): def __init__(self, stream=None):
from calibre import prints
self._prints = partial(prints, safe_encode=True)
if stream is None: if stream is None:
stream = cStringIO.StringIO() stream = cStringIO.StringIO()
self.stream = stream self.stream = stream
self._prints = partial(prints, safe_encode=True, file=stream)
def flush(self): def flush(self):
self.stream.flush() self.stream.flush()
@ -53,7 +52,6 @@ class FileStream(Stream):
Stream.__init__(self, stream) Stream.__init__(self, stream)
def prints(self, level, *args, **kwargs): def prints(self, level, *args, **kwargs):
kwargs['file'] = self.stream
self._prints(*args, **kwargs) self._prints(*args, **kwargs)
class HTMLStream(Stream): class HTMLStream(Stream):
@ -171,18 +169,24 @@ class ThreadSafeLog(Log):
def __init__(self, level=Log.INFO): def __init__(self, level=Log.INFO):
Log.__init__(self, level=level) Log.__init__(self, level=level)
self._lock = RLock() self._lock = Lock()
def prints(self, *args, **kwargs): def prints(self, *args, **kwargs):
with self._lock: with self._lock:
Log.prints(self, *args, **kwargs) Log.prints(self, *args, **kwargs)
def exception(self, *args, **kwargs):
limit = kwargs.pop('limit', None)
with self._lock:
Log.prints(self, ERROR, *args, **kwargs)
Log.prints(self, DEBUG, traceback.format_exc(limit))
class ThreadSafeWrapper(Log): class ThreadSafeWrapper(Log):
def __init__(self, other_log): def __init__(self, other_log):
Log.__init__(self, level=other_log.filter_level) Log.__init__(self, level=other_log.filter_level)
self.outputs = list(other_log.outputs) self.outputs = list(other_log.outputs)
self._lock = RLock() self._lock = Lock()
def prints(self, *args, **kwargs): def prints(self, *args, **kwargs):
with self._lock: with self._lock: