diff options
Diffstat (limited to '_shm/shm_wrapper.py')
-rw-r--r-- | _shm/shm_wrapper.py | 302 |
1 files changed, 0 insertions, 302 deletions
diff --git a/_shm/shm_wrapper.py b/_shm/shm_wrapper.py deleted file mode 100644 index 851f588..0000000 --- a/_shm/shm_wrapper.py +++ /dev/null @@ -1,302 +0,0 @@ -# shm_wrapper - A wrapper for the shm module which provides access -# to System V shared memory and semaphores on *nix systems. -# -# Copyright (c) 2007 by Philip Semanchuk -# Contact info at http://NikitaTheSpider.com/ -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - -# Python modules -import random -import sys - -# Third party modules -import shm -from shm import error as shmerror - -r"""shm_wrapper - A wrapper for the shm module which provides access -to System V shared memory and semaphores on *nix systems. - -The module shm is a Python wrapper around system functions like shmget. This -module in turn offers higher-level, more Pythonic access to shared memory and -semaphores. - -Full documentation is online at http://NikitaTheSpider.com/python/shm/ - -""" - -def create_memory(size, permissions = 0666, InitCharacter = ' '): - """ Creates a new shared memory segment. One can destroy it either by calling the - module-level method remove_memory() or by calling the .remove() method of a handle to - said memory. - """ - memory = None - - # I create the memory using a randomly-generated key. I keep trying until I find one - # that works or until I hit an error. - while not memory: - key = random.randint(1, sys.maxint - 1) - try: - memory = shm.create_memory(key, size, permissions) - except shmerror, ExtraData: - if shm.memory_haskey(key): - # Oops, bad luck, the key exists. I'll try another. I can't call - # memory_haskey() before calling create_memory() because that would create - # a race condition where I could verify a key is not used but then another - # process could call create_memory() with that key before I got a chance to - # do so. - pass - else: - # Uh-oh, something fundamental is wrong. - raise shmerror, ExtraData - - # Here I implicitly discard the memory handle object returned to me by shm and instead - # return my own handle to the shared memory segment. - memory = SharedMemoryHandle(key) - - memory.write(InitCharacter[0] * memory.size) - - return memory - - -def remove_memory(key): - # Destroys the shared memory segment. Raises KeyError if the key doesn't exist. - shm.remove_memory(shm.getshmid(key)) - - -class SharedMemoryHandle(object): - def __init__(self, key): - self._MemoryHandle = None - - # getshmid will raise a KeyError if there's no memory segment with this key. - shmid = shm.getshmid(key) - self._MemoryHandle = shm.memory(shmid) - - - def __del__(self): - if self._MemoryHandle: - # This will raise an error if the memory has been destroyed. - try: - if self._MemoryHandle.attached: - self._MemoryHandle.detach() - except shmerror: - pass - - - def remove(self): - if self._MemoryHandle: - if self._MemoryHandle.attached: - self._MemoryHandle.detach() - - shm.remove_memory(self._MemoryHandle.shmid) - self._MemoryHandle = None - - - def read(self, NumberOfBytes = 0, offset = 0): - if not self._MemoryHandle.attached: - self._MemoryHandle.attach() - - if not NumberOfBytes: - NumberOfBytes = self._MemoryHandle.size - offset - - return self._MemoryHandle.read(NumberOfBytes, offset) - - - def write(self, s, offset = 0): - if not self._MemoryHandle.attached: - self._MemoryHandle.attach() - - self._MemoryHandle.write(s, offset) - - - # Properties start here ================================================================ - - # key - def __get_key(self): return self._MemoryHandle.key - def __set_key(self, foo): raise AttributeError - key = property(__get_key, __set_key) - - # size of segment - def __get_size(self): return self._MemoryHandle.size - def __set_size(self, foo): raise AttributeError - size = property(__get_size, __set_size) - - # permissions - def __get_permissions(self): return self._MemoryHandle.perm - def __set_permissions(self, permissions): self._MemoryHandle.setperm(permissions) - permissions = property(__get_permissions, __set_permissions) - - # The number of processes currently attached to this memory segment. - def __get_number_attached(self): return self._MemoryHandle.nattch - def __set_number_attached(self, foo): raise AttributeError - number_attached = property(__get_number_attached, __set_number_attached) - - # segment's uid - def __get_uid(self): return self._MemoryHandle.uid - def __set_uid(self, uid): self._MemoryHandle.setuid(uid) - uid = property(__get_uid, __set_uid) - - # segment's gid - def __get_gid(self): return self._MemoryHandle.gid - def __set_gid(self, gid): self._MemoryHandle.setgid(gid) - gid = property(__get_gid, __set_gid) - - # Creator uid (read-only) - def __get_creator_uid(self): return self._MemoryHandle.cuid - def __set_creator_uid(self, foo): raise AttributeError - creator_uid = property(__get_creator_uid, __set_creator_uid) - - # Creator gid (read-only) - def __get_creator_gid(self): return self._MemoryHandle.cgid - def __set_creator_gid(self, foo): raise AttributeError - creator_gid = property(__get_creator_gid, __set_creator_gid) - - # Creator pid (read-only) - def __get_creator_pid(self): return self._MemoryHandle.cpid - def __set_creator_pid(self, foo): raise AttributeError - creator_pid = property(__get_creator_pid, __set_creator_pid) - - # pid of last process to operate on this segment (read-only) - def __get_last_pid(self): return self._MemoryHandle.lpid - def __set_last_pid(self, foo): raise AttributeError - last_pid = property(__get_last_pid, __set_last_pid) - - - -def create_semaphore(InitialValue = 1, permissions = 0666): - """ Creates a new semaphore. One can destroy it either by calling the - module-level method remove_semaphore() or by calling the .remove() method of a - handle to said semaphore. - """ - semaphore = None - - # I create the semaphore using a randomly-generated key. I keep trying until I find one - # that works or until I hit an error. - while not semaphore: - key = random.randint(1, sys.maxint - 1) - try: - semaphore = shm.create_semaphore(key, InitialValue, permissions) - except shmerror, ExtraData: - if shm.semaphore_haskey(key): - # Oops, bad luck, the key exists. I'll try another. I can't call - # memory_haskey() before calling create_semaphore() because that would create - # a race condition where I could verify a key is not used but then another - # process could call create_semaphore() with that key before I got a chance to - # do so. - pass - else: - # Uh-oh, something fundamental is wrong. - raise ExtraData - - # Here I implicitly discard the semaphore object returned to me by shm and instead - # return my own handle to the semaphore. - return SemaphoreHandle(key) - - -def remove_semaphore(key): - # Destroys the semaphore. Raises KeyError if the key doesn't exist. - shm.remove_semaphore(shm.getsemid(key)) - - -class SemaphoreHandle(object): - def __init__(self, key): - # getsemid will raise a KeyError if appropriate. - self._SemaphoreHandle = shm.semaphore(shm.getsemid(key)) - - - def remove(self): - shm.remove_semaphore(self._SemaphoreHandle.semid) - self._SemaphoreHandle = None - - - def P(self): - # P = prolaag = probeer te verlagen (try to decrease) - self._SemaphoreHandle.P() - - - def V(self): - # V = verhoog (increase) - self._SemaphoreHandle.V() - - - def Z(self): - # Z = block until Zee semaphore is Zero - self._SemaphoreHandle.Z() - - - # Properties start here ================================================================ - def __get_key(self): return self._SemaphoreHandle.key - def __set_key(self, foo): raise AttributeError - key = property(__get_key, __set_key) - - - def __get_value(self): return self._SemaphoreHandle.val - def __set_value(self, value): self._semaphore.setval(value) - value = property(__get_value, __set_value) - - - def __get_WaitingForZero(self): return self._SemaphoreHandle.zcnt - def __set_WaitingForZero(self, foo): raise AttributeError - WaitingForZero = property(__get_WaitingForZero, __set_WaitingForZero) - - - def __get_WaitingForNonZero(self): return self._SemaphoreHandle.ncnt - def __set_WaitingForNonZero(self, foo): raise AttributeError - WaitingForNonZero = property(__get_WaitingForNonZero, __set_WaitingForNonZero) - - - def __get_blocking(self): return self._SemaphoreHandle.blocking - def __set_blocking(self, block): self._SemaphoreHandle.setblocking(block) - blocking = property(__get_blocking, __set_blocking) - - - def __get_undo(self): raise AttributeError - def __set_undo(self, undo): self._SemaphoreHandle.setundo(undo) - undo = property(__get_undo, __set_undo) - - - # segment's uid - def __get_uid(self): return self._SemaphoreHandle.uid - def __set_uid(self, uid): self._SemaphoreHandle.setuid(uid) - uid = property(__get_uid, __set_uid) - - - # segment's gid - def __get_gid(self): return self._SemaphoreHandle.gid - def __set_gid(self, gid): self._SemaphoreHandle.setgid(gid) - gid = property(__get_gid, __set_gid) - - - # Creator uid (read-only) - def __get_creator_uid(self): return self._SemaphoreHandle.cuid - def __set_creator_uid(self, foo): raise AttributeError - creator_uid = property(__get_creator_uid, __set_creator_uid) - - - # Creator gid (read-only) - def __get_creator_gid(self): return self._SemaphoreHandle.cgid - def __set_creator_gid(self, foo): raise AttributeError - creator_gid = property(__get_creator_gid, __set_creator_gid) - - - # Creator pid -- since semaphores have a lot of the same properties as memory - # objects, one would expect creator PID to be exposed here, but it isn't - # made available by the system (true AFAICT for BSDs, OS X and Solaris). - - - # pid of last process to operate on this segment (read-only) - def __get_last_pid(self): return self._SemaphoreHandle.lpid - def __set_last_pid(self, foo): raise AttributeError - last_pid = property(__get_last_pid, __set_last_pid) |