Skip to content

Commit

Permalink
Remove dual_color.Semaphore
Browse files Browse the repository at this point in the history
  • Loading branch information
mikeshardmind committed Jan 15, 2025
1 parent 01e4891 commit 0396bc6
Show file tree
Hide file tree
Showing 2 changed files with 2 additions and 152 deletions.
150 changes: 0 additions & 150 deletions src/async_utils/_qs.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,156 +192,6 @@ def set(self, /) -> bool:
return success


class Semaphore:
__slots__ = (
"__weakref__",
"_unlocked",
"_value",
"_waiters",
)

def __init__(self, value: int = 1, /) -> None:
self._value: int = value
self._waiters: deque[AsyncEvent | ThreadingEvent] = deque()
self._unlocked: list[None] = [None] * self._value

async def __aenter__(self, /) -> t.Self:
await self.async_acquire()
return self

async def __aexit__(self, *dont_care: object) -> None:
self.release()

def __enter__(self, /) -> t.Self:
self.sync_acquire()

return self

def __exit__(self, *dont_care: object) -> None:
self.release()

def _acquire_nowait(self, /) -> bool:
if unlocked := self._unlocked:
try:
unlocked.pop()
except IndexError:
success = False
else:
success = True
else:
success = False

return success

async def async_acquire(self) -> bool:
waiters = self._waiters
success = self._acquire_nowait()
rescheduled = False

if not success:
waiters.append(event := AsyncEvent())

try:
success = self._acquire_nowait()

if not success:
success = await event
rescheduled = True
finally:
if success or event.cancel():
try:
waiters.remove(event)
except ValueError:
pass
else:
self.release()

if not rescheduled:
await asyncio.sleep(0)

return success

def sync_acquire(
self, /, *, blocking: bool = True, timeout: float | None = None
) -> bool:
waiters = self._waiters
success = self._acquire_nowait()

if success := self._acquire_nowait():
return True

if not blocking:
return False

waiters.append(event := ThreadingEvent())

try:
success = self._acquire_nowait()

if not success:
success = event.wait(timeout)
finally:
if success or event.cancel():
try:
waiters.remove(event)
except ValueError:
pass
else:
self.release()

return success

def release(self) -> None:
waiters = self._waiters
unlocked = self._unlocked
count = 1

while True:
if waiters:
if not count:
if self._acquire_nowait():
count = 1
else:
break

try:
event = waiters[0]
except IndexError:
pass
else:
if event.is_set():
count -= 1

try:
waiters.remove(event)
except ValueError:
pass

if count or unlocked:
continue
break

if count == 1:
unlocked.append(None)
elif count > 1:
unlocked.extend([None] * count)
else:
break

if waiters:
count = 0
else:
break

@property
def waiting(self, /) -> int:
return len(self._waiters)

@property
def value(self, /) -> int:
return len(self._unlocked)


class _BaseQueue[T]:
__slots__ = (
"__get_waiters",
Expand Down
4 changes: 2 additions & 2 deletions src/async_utils/dual_color.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@

from __future__ import annotations

from ._qs import LIFOQueue, PriorityQueue, Queue, QueueEmpty, QueueFull, Semaphore
from ._qs import LIFOQueue, PriorityQueue, Queue, QueueEmpty, QueueFull

__all__ = ("LIFOQueue", "PriorityQueue", "Queue", "QueueEmpty", "QueueFull", "Semaphore")
__all__ = ("LIFOQueue", "PriorityQueue", "Queue", "QueueEmpty", "QueueFull")

0 comments on commit 0396bc6

Please sign in to comment.