aboutsummaryrefslogtreecommitdiffstats
path: root/src/unified_posix_ipc.py
diff options
context:
space:
mode:
authorMattias Andrée <maandree@operamail.com>2014-06-14 21:59:41 +0200
committerMattias Andrée <maandree@operamail.com>2014-06-14 21:59:41 +0200
commit2d53c1408f6a10c3fb4f88f5980fe5a16c9025d3 (patch)
tree77723456741e89d4da758c8766c81618f4149e72 /src/unified_posix_ipc.py
parentfinish common api for mqueue (diff)
downloadcmdipc-2d53c1408f6a10c3fb4f88f5980fe5a16c9025d3.tar.gz
cmdipc-2d53c1408f6a10c3fb4f88f5980fe5a16c9025d3.tar.bz2
cmdipc-2d53c1408f6a10c3fb4f88f5980fe5a16c9025d3.tar.xz
m + z and barriers under -P
Signed-off-by: Mattias Andrée <maandree@operamail.com>
Diffstat (limited to 'src/unified_posix_ipc.py')
-rw-r--r--src/unified_posix_ipc.py51
1 files changed, 45 insertions, 6 deletions
diff --git a/src/unified_posix_ipc.py b/src/unified_posix_ipc.py
index b73ff45..05e9b16 100644
--- a/src/unified_posix_ipc.py
+++ b/src/unified_posix_ipc.py
@@ -39,13 +39,52 @@ class Semaphore(posix_ipc.Semaphore):
def __init__(self, *args, **kwargs):
posix_ipc.Semaphore.__init__(self, *args, **kwargs)
self.key = self.name
- def P(self, timeout = None):
- self.acquire(timeout)
- def V(self):
- self.release()
+ def acquire(self, timeout = None, delta = 1):
+ have = 0
+ try:
+ for _ in range(abs(delta)):
+ posix_ipc.Semaphore.acquire(self, timeout)
+ have += 1
+ except Exception as e:
+ try:
+ self.release(have)
+ except:
+ pass
+ raise e
+ def release(self, delta = 1):
+ for _ in range(abs(delta)):
+ posix_ipc.Semaphore.release(self)
+ def P(self, timeout = None, delta = 1):
+ self.acquire(timeout, delta)
+ def V(self, delta = 1):
+ self.release(delta)
+ def Z(self, timeout = None):
+ if not timeout == 0:
+ import sys
+ print('Z operation over POSIX semaphore require spinlock', file = sys.stderr)
+ if timeout is None:
+ while not self.value == 0:
+ pass
+ elif timeout == 0:
+ if not self.value == 0:
+ raise BusyError()
+ else:
+ import time
+ end = time.monotonic() + timeout
+ while not self.value == 0:
+ if time.monotonic() > end:
+ raise BusyError()
def set_value(self, value):
- for _ in range(value):
- self.V()
+ n = abs(value) - self.value
+ try:
+ if n > 0:
+ for _ in range(n):
+ self.V()
+ elif n < 0:
+ for _ in range(-n):
+ self.P(0)
+ except BusyError:
+ pass
def remove(self):
self.unlink()
self.close()