Skip to content

Commit

Permalink
fix: use a re-entrant lock to avoid self-deadlocking #1310
Browse files Browse the repository at this point in the history
  • Loading branch information
nedbat committed Jan 30, 2022
1 parent e6a8102 commit ea71ae9
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 1 deletion.
6 changes: 5 additions & 1 deletion coverage/sqldata.py
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ def __init__(self, basename=None, suffix=None, no_disk=False, warn=None, debug=N
self._dbs = {}
self._pid = os.getpid()
# Synchronize the operations used during collection.
self._lock = threading.Lock()
self._lock = threading.RLock()

# Are we in sync with the data file?
self._have_used = False
Expand All @@ -231,7 +231,11 @@ def _locked(method): # pylint: disable=no-self-argument
"""A decorator for methods that should hold self._lock."""
@functools.wraps(method)
def _wrapped(self, *args, **kwargs):
if self._debug.should("lock"):
self._debug.write(f"Locking {self._lock!r} for {method.__name__}")
with self._lock:
if self._debug.should("lock"):
self._debug.write(f"Locked {self._lock!r} for {method.__name__}")
# pylint: disable=not-callable
return method(self, *args, **kwargs)
return _wrapped
Expand Down
2 changes: 2 additions & 0 deletions doc/cmd.rst
Original file line number Diff line number Diff line change
Expand Up @@ -969,6 +969,8 @@ of operation to log:

* ``dataop``: log when data is added to the CoverageData object.

* ``lock``: log operations acquiring locks in the data layer.

* ``multiproc``: log the start and stop of multiprocessing processes.

* ``pid``: annotate all warnings and debug output with the process and thread
Expand Down

0 comments on commit ea71ae9

Please sign in to comment.