diff options
| author | Mattias Andrée <maandree@operamail.com> | 2014-06-14 21:59:41 +0200 |
|---|---|---|
| committer | Mattias Andrée <maandree@operamail.com> | 2014-06-14 21:59:41 +0200 |
| commit | 2d53c1408f6a10c3fb4f88f5980fe5a16c9025d3 (patch) | |
| tree | 77723456741e89d4da758c8766c81618f4149e72 /src | |
| parent | finish common api for mqueue (diff) | |
| download | cmdipc-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')
| -rwxr-xr-x | src/cmdipc | 72 | ||||
| -rw-r--r-- | src/unified_posix_ipc.py | 51 |
2 files changed, 96 insertions, 27 deletions
@@ -66,7 +66,7 @@ parser.add_argumentless(['-S', '--semaphore'], 0, 'Use semaphore') parser.add_argumentless(['-M', '--shm'], 0, 'Use shared memory') parser.add_argumentless(['-X', '--mutex'], 0, 'Use mutex (1 semaphore)') parser.add_argumentless(['-C', '--condition'], 0, 'Use condition (3 semaphores)') -parser.add_argumentless(['-B', '--barrier'], 0, 'Use barrier (2 semaphores, SysV only)') +parser.add_argumentless(['-B', '--barrier'], 0, 'Use barrier (2 semaphores, -P: 3 semaphores)') parser.add_argumentless(['-L', '--shared-lock'], 0, 'Use shared lock (3 semaphores)') parser.add_argumentless(['-R', '--rendezvous'], 0, 'Use rendezvous (2 semaphores, 1 mqueue, SysV only)') @@ -147,7 +147,7 @@ try: nocmd = False if (len(parser.files) == 1) and (parser.files[0] == 'p'): s.P(timeout, delta) elif (len(parser.files) == 1) and (parser.files[0] == 'v'): s.V(delta) - elif (len(parser.files) == 1) and (parser.files[0] == 'z') and (not use_posix): s.Z(timeout) + elif (len(parser.files) == 1) and (parser.files[0] == 'z'): s.Z(timeout) elif (len(parser.files) == 1) and (parser.files[0] == 'read'): print('%i' % s.value) elif (len(parser.files) == 2) and (parser.files[0] == 'set'): s.set_value(int(parser.files[1])) elif key is not None: @@ -253,8 +253,10 @@ try: print('Invalid command given', file = sys.stderr) sys.exit(1) - elif (not use_posix) and (parser.opts['--barrier'] is not None): + elif parser.opts['--barrier'] is not None: key, flags, mode, timeout = [None, None], 0, 0o600, None + if use_posix: + key = [None, None, None] if parser.opts['--nonblocking'] is not None: timeout = 0 if parser.opts['--key'] is not None: key = ipc.keysep(parser.opts['--key'][0]) if parser.opts['--create'] is not None: flags = ipc.CREAT @@ -268,30 +270,58 @@ try: sys.exit(1) else: threshold = int(parser.files[0]) - s = ipc.Semaphore(key[0], flags, mode, threshold) - m = ipc.Semaphore(key[1], flags, mode, 1) - if key[0] is None: - print('key: %s' % ipc.keycat(s.key, m.key)) + if not use_posix: + s = ipc.Semaphore(key[0], flags, mode, threshold) + m = ipc.Semaphore(key[1], flags, mode, 1) + if key[0] is None: + print('key: %s' % ipc.keycat(s.key, m.key)) + else: + x = ipc.Semaphore(key[0], flags, mode, 1) + c = ipc.Semaphore(key[1], flags, mode, 0) + q = ipc.Semaphore(key[2], flags, mode, 0) + if key[0] is None: + print('key: %s' % ipc.keycat(x.key, c.key, q.key)) nocmd = False if (len(parser.files) == 2) and (parser.files[1] == 'enter'): - s.P(timeout) - s.Z(timeout) - try: - m.P(0) - except ipc.BusyError: - pass + if not use_posix: + s.P(timeout) + s.Z(timeout) + try: + m.P(0) + except ipc.BusyError: + pass + else: + if s.value == 0: + s.set_value(threshold) + m.V() else: - if s.value == 0: - s.set_value(threshold) - m.V() + x.P(timeout) + c.V() + if c.value == threshold: + q.V(threshold - 1) + c.set_value(0) + x.V() + else: + x.V() + q.P(timeout) elif key[0] is not None: nocmd = True if parser.opts['--remove'] is not None: - s.remove() - m.remove() + if not use_posix: + s.remove() + m.remove() + else: + x.remove() + c.remove() + q.remove() elif nocmd: - s.close() - m.close() + if not use_posix: + s.close() + m.close() + else: + x.close() + c.close() + q.close() print('Invalid command given', file = sys.stderr) sys.exit(1) @@ -395,5 +425,5 @@ except ipc.SignalError: sys.exit(5) except ipc.PermissionsError: sys.exit(4) except ipc.ExistentialError: sys.exit(3) except ipc.BusyError: sys.exit(2) -except: sys.exit(1) +#except: sys.exit(1) 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() |
