Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Lib/test/test_free_threading/test_monitoring.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from contextlib import contextmanager
from sys import monitoring
from test.support import threading_helper
from threading import Thread, _PyRLock, Barrier
from threading import Thread, RLock, Barrier
from unittest import TestCase


Expand Down Expand Up @@ -301,7 +301,7 @@ def trace(frame, event, arg):

sys.settrace(trace)
try:
l = _PyRLock()
l = RLock()

def f():
for i in range(loops):
Expand Down
8 changes: 2 additions & 6 deletions Lib/test/test_threading.py
Original file line number Diff line number Diff line change
Expand Up @@ -2264,12 +2264,8 @@ def _callback_spy(self, *args, **kwargs):
class LockTests(lock_tests.LockTests):
locktype = staticmethod(threading.Lock)

class PyRLockTests(lock_tests.RLockTests):
locktype = staticmethod(threading._PyRLock)

@unittest.skipIf(threading._CRLock is None, 'RLock not implemented in C')
class CRLockTests(lock_tests.RLockTests):
locktype = staticmethod(threading._CRLock)
class RLockTests(lock_tests.RLockTests):
locktype = staticmethod(threading.RLock)

def test_signature(self): # gh-102029
with warnings.catch_warnings(record=True) as warnings_log:
Expand Down
149 changes: 1 addition & 148 deletions Lib/threading.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,7 @@
except AttributeError:
_set_name = None
ThreadError = _thread.error
try:
_CRLock = _thread.RLock
except AttributeError:
_CRLock = None
RLock = _thread.RLock
TIMEOUT_MAX = _thread.TIMEOUT_MAX
del _thread

Expand Down Expand Up @@ -123,150 +120,6 @@ def gettrace():

Lock = _LockType

def RLock():
"""Factory function that returns a new reentrant lock.

A reentrant lock must be released by the thread that acquired it. Once a
thread has acquired a reentrant lock, the same thread may acquire it again
without blocking; the thread must release it once for each time it has
acquired it.

"""
if _CRLock is None:
return _PyRLock()
return _CRLock()

class _RLock:
"""This class implements reentrant lock objects.

A reentrant lock must be released by the thread that acquired it. Once a
thread has acquired a reentrant lock, the same thread may acquire it
again without blocking; the thread must release it once for each time it
has acquired it.

"""

def __init__(self):
self._block = _allocate_lock()
self._owner = None
self._count = 0

def __repr__(self):
owner = self._owner
try:
owner = _active[owner].name
except KeyError:
pass
return "<%s %s.%s object owner=%r count=%d at %s>" % (
"locked" if self.locked() else "unlocked",
self.__class__.__module__,
self.__class__.__qualname__,
owner,
self._count,
hex(id(self))
)

def _at_fork_reinit(self):
self._block._at_fork_reinit()
self._owner = None
self._count = 0

def acquire(self, blocking=True, timeout=-1):
"""Acquire a lock, blocking or non-blocking.

When invoked without arguments: if this thread already owns the lock,
increment the recursion level by one, and return immediately. Otherwise,
if another thread owns the lock, block until the lock is unlocked. Once
the lock is unlocked (not owned by any thread), then grab ownership, set
the recursion level to one, and return. If more than one thread is
blocked waiting until the lock is unlocked, only one at a time will be
able to grab ownership of the lock. There is no return value in this
case.

When invoked with the blocking argument set to true, do the same thing
as when called without arguments, and return true.

When invoked with the blocking argument set to false, do not block. If a
call without an argument would block, return false immediately;
otherwise, do the same thing as when called without arguments, and
return true.

When invoked with the floating-point timeout argument set to a positive
value, block for at most the number of seconds specified by timeout
and as long as the lock cannot be acquired. Return true if the lock has
been acquired, false if the timeout has elapsed.

"""
me = get_ident()
if self._owner == me:
self._count += 1
return 1
rc = self._block.acquire(blocking, timeout)
if rc:
self._owner = me
self._count = 1
return rc

__enter__ = acquire

def release(self):
"""Release a lock, decrementing the recursion level.

If after the decrement it is zero, reset the lock to unlocked (not owned
by any thread), and if any other threads are blocked waiting for the
lock to become unlocked, allow exactly one of them to proceed. If after
the decrement the recursion level is still nonzero, the lock remains
locked and owned by the calling thread.

Only call this method when the calling thread owns the lock. A
RuntimeError is raised if this method is called when the lock is
unlocked.

There is no return value.

"""
if self._owner != get_ident():
raise RuntimeError("cannot release un-acquired lock")
self._count = count = self._count - 1
if not count:
self._owner = None
self._block.release()

def __exit__(self, t, v, tb):
self.release()

def locked(self):
"""Return whether this object is locked."""
return self._block.locked()

# Internal methods used by condition variables

def _acquire_restore(self, state):
self._block.acquire()
self._count, self._owner = state

def _release_save(self):
if self._count == 0:
raise RuntimeError("cannot release un-acquired lock")
count = self._count
self._count = 0
owner = self._owner
self._owner = None
self._block.release()
return (count, owner)

def _is_owned(self):
return self._owner == get_ident()

# Internal method used for reentrancy checks

def _recursion_count(self):
if self._owner != get_ident():
return 0
return self._count

_PyRLock = _RLock


class Condition:
"""Class that implements a condition variable.
Expand Down
Loading