Fast semaphore.
| 72 | |
| 73 | #c cdef class Semaphore: |
| 74 | class Semaphore(object): #p |
| 75 | """Fast semaphore. |
| 76 | """ |
| 77 | #c cdef pythread.PyThread_type_lock _lock |
| 78 | #c cdef int _value |
| 79 | |
| 80 | #c def __cinit__(self, int value=1): |
| 81 | def __init__(self, value=1): #p |
| 82 | if value < 0: |
| 83 | raise ValueError("Semaphore: Parameter 'value' must not be less than 0") |
| 84 | #c self._lock = pythread.PyThread_allocate_lock() |
| 85 | #c if not self._lock: |
| 86 | #c raise MemoryError() |
| 87 | self._lock = Lock() #p |
| 88 | #c pythread.PyThread_acquire_lock(self._lock, pythread.NOWAIT_LOCK) |
| 89 | self._lock.acquire(False) #p |
| 90 | self._value = value |
| 91 | |
| 92 | #c def __dealloc__(self): |
| 93 | #c if self._lock: |
| 94 | #c pythread.PyThread_free_lock(self._lock) |
| 95 | #c self._lock = NULL |
| 96 | |
| 97 | @property |
| 98 | def value(self): |
| 99 | return self._value |
| 100 | |
| 101 | #c cpdef bint acquire(self, bint blocking=True): |
| 102 | def acquire(self, blocking=True): #p |
| 103 | #c cdef int wait |
| 104 | if self._value >= 0: |
| 105 | self._value -= 1 |
| 106 | if self._value >= 0: |
| 107 | return False |
| 108 | #c with nogil: |
| 109 | if True: #p |
| 110 | #c wait = pythread.WAIT_LOCK if blocking else pythread.NOWAIT_LOCK |
| 111 | wait = blocking #p |
| 112 | while True: |
| 113 | #c if pythread.PyThread_acquire_lock(self._lock, wait): |
| 114 | if self._lock.acquire(wait): #p |
| 115 | break |
| 116 | #c if wait == pythread.NOWAIT_LOCK: |
| 117 | if not wait: #p |
| 118 | return False |
| 119 | return True |
| 120 | |
| 121 | #c cpdef void release(self): |
| 122 | def release(self): #p |
| 123 | self._value += 1 |
| 124 | if self._value >= 0: |
| 125 | #c pythread.PyThread_release_lock(self._lock) |
| 126 | try: #p |
| 127 | self._lock.release() #p |
| 128 | except RuntimeError: #p |
| 129 | pass #p |
| 130 | |
| 131 |