1edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# 2edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# Module which supports allocation of ctypes objects from shared memory 3edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# 4edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# multiprocessing/sharedctypes.py 5edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# 6edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# Copyright (c) 2006-2008, R Oudkerk 7edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# All rights reserved. 8edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# 9edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# Redistribution and use in source and binary forms, with or without 10edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# modification, are permitted provided that the following conditions 11edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# are met: 12edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# 13edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# 1. Redistributions of source code must retain the above copyright 14edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# notice, this list of conditions and the following disclaimer. 15edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# 2. Redistributions in binary form must reproduce the above copyright 16edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# notice, this list of conditions and the following disclaimer in the 17edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# documentation and/or other materials provided with the distribution. 18edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# 3. Neither the name of author nor the names of any contributors may be 19edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# used to endorse or promote products derived from this software 20edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# without specific prior written permission. 21edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# 22edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND 23edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 26edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# SUCH DAMAGE. 33edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# 34edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 35edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepimport sys 36edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepimport ctypes 37edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepimport weakref 38edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 39edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepfrom multiprocessing import heap, RLock 40edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepfrom multiprocessing.forking import assert_spawning, ForkingPickler 41edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 42edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep__all__ = ['RawValue', 'RawArray', 'Value', 'Array', 'copy', 'synchronized'] 43edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 44edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# 45edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# 46edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# 47edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 48edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoeptypecode_to_type = { 49edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'c': ctypes.c_char, 'u': ctypes.c_wchar, 50edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'b': ctypes.c_byte, 'B': ctypes.c_ubyte, 51edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'h': ctypes.c_short, 'H': ctypes.c_ushort, 52edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'i': ctypes.c_int, 'I': ctypes.c_uint, 53edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'l': ctypes.c_long, 'L': ctypes.c_ulong, 54edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 'f': ctypes.c_float, 'd': ctypes.c_double 55edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep } 56edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 57edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# 58edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# 59edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# 60edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 61edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepdef _new_value(type_): 62edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep size = ctypes.sizeof(type_) 63edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep wrapper = heap.BufferWrapper(size) 64edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return rebuild_ctype(type_, wrapper, None) 65edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 66edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepdef RawValue(typecode_or_type, *args): 67edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ''' 68edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Returns a ctypes object allocated from shared memory 69edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ''' 70edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep type_ = typecode_to_type.get(typecode_or_type, typecode_or_type) 71edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep obj = _new_value(type_) 72edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ctypes.memset(ctypes.addressof(obj), 0, ctypes.sizeof(obj)) 73edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep obj.__init__(*args) 74edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return obj 75edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 76edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepdef RawArray(typecode_or_type, size_or_initializer): 77edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ''' 78edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Returns a ctypes array allocated from shared memory 79edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ''' 80edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep type_ = typecode_to_type.get(typecode_or_type, typecode_or_type) 81edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if isinstance(size_or_initializer, (int, long)): 82edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep type_ = type_ * size_or_initializer 83edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep obj = _new_value(type_) 84edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ctypes.memset(ctypes.addressof(obj), 0, ctypes.sizeof(obj)) 85edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return obj 86edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 87edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep type_ = type_ * len(size_or_initializer) 88edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep result = _new_value(type_) 89edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep result.__init__(*size_or_initializer) 90edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return result 91edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 92edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepdef Value(typecode_or_type, *args, **kwds): 93edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ''' 94edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Return a synchronization wrapper for a Value 95edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ''' 96edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep lock = kwds.pop('lock', None) 97edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if kwds: 98edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep raise ValueError('unrecognized keyword argument(s): %s' % kwds.keys()) 99edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep obj = RawValue(typecode_or_type, *args) 100edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if lock is False: 101edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return obj 102edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if lock in (True, None): 103edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep lock = RLock() 104edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if not hasattr(lock, 'acquire'): 105edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep raise AttributeError("'%r' has no method 'acquire'" % lock) 106edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return synchronized(obj, lock) 107edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 108edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepdef Array(typecode_or_type, size_or_initializer, **kwds): 109edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ''' 110edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep Return a synchronization wrapper for a RawArray 111edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ''' 112edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep lock = kwds.pop('lock', None) 113edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if kwds: 114edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep raise ValueError('unrecognized keyword argument(s): %s' % kwds.keys()) 115edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep obj = RawArray(typecode_or_type, size_or_initializer) 116edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if lock is False: 117edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return obj 118edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if lock in (True, None): 119edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep lock = RLock() 120edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if not hasattr(lock, 'acquire'): 121edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep raise AttributeError("'%r' has no method 'acquire'" % lock) 122edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return synchronized(obj, lock) 123edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 124edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepdef copy(obj): 125edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep new_obj = _new_value(type(obj)) 126edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ctypes.pointer(new_obj)[0] = obj 127edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return new_obj 128edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 129edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepdef synchronized(obj, lock=None): 130edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep assert not isinstance(obj, SynchronizedBase), 'object already synchronized' 131edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 132edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if isinstance(obj, ctypes._SimpleCData): 133edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return Synchronized(obj, lock) 134edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep elif isinstance(obj, ctypes.Array): 135edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if obj._type_ is ctypes.c_char: 136edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return SynchronizedString(obj, lock) 137edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return SynchronizedArray(obj, lock) 138edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 139edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep cls = type(obj) 140edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep try: 141edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep scls = class_cache[cls] 142edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep except KeyError: 143edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep names = [field[0] for field in cls._fields_] 144edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep d = dict((name, make_property(name)) for name in names) 145edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep classname = 'Synchronized' + cls.__name__ 146edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep scls = class_cache[cls] = type(classname, (SynchronizedBase,), d) 147edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return scls(obj, lock) 148edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 149edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# 150edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# Functions for pickling/unpickling 151edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# 152edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 153edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepdef reduce_ctype(obj): 154edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep assert_spawning(obj) 155edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if isinstance(obj, ctypes.Array): 156edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return rebuild_ctype, (obj._type_, obj._wrapper, obj._length_) 157edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep else: 158edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return rebuild_ctype, (type(obj), obj._wrapper, None) 159edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 160edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepdef rebuild_ctype(type_, wrapper, length): 161edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep if length is not None: 162edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep type_ = type_ * length 163edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep ForkingPickler.register(type_, reduce_ctype) 164edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep obj = type_.from_address(wrapper.get_address()) 165edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep obj._wrapper = wrapper 166edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return obj 167edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 168edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# 169edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# Function to create properties 170edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# 171edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 172edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepdef make_property(name): 173edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep try: 174edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return prop_cache[name] 175edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep except KeyError: 176edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep d = {} 177edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep exec template % ((name,)*7) in d 178edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep prop_cache[name] = d[name] 179edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return d[name] 180edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 181edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoeptemplate = ''' 182edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepdef get%s(self): 183edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.acquire() 184edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep try: 185edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return self._obj.%s 186edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep finally: 187edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.release() 188edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepdef set%s(self, value): 189edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.acquire() 190edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep try: 191edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._obj.%s = value 192edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep finally: 193edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.release() 194edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep%s = property(get%s, set%s) 195edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep''' 196edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 197edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepprop_cache = {} 198edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass_cache = weakref.WeakKeyDictionary() 199edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 200edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# 201edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# Synchronized wrappers 202edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep# 203edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 204edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass SynchronizedBase(object): 205edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 206edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def __init__(self, obj, lock=None): 207edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._obj = obj 208edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._lock = lock or RLock() 209edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.acquire = self._lock.acquire 210edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.release = self._lock.release 211edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 212edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def __reduce__(self): 213edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep assert_spawning(self) 214edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return synchronized, (self._obj, self._lock) 215edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 216edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def get_obj(self): 217edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return self._obj 218edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 219edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def get_lock(self): 220edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return self._lock 221edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 222edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def __repr__(self): 223edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return '<%s wrapper for %s>' % (type(self).__name__, self._obj) 224edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 225edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 226edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass Synchronized(SynchronizedBase): 227edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep value = make_property('value') 228edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 229edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 230edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass SynchronizedArray(SynchronizedBase): 231edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 232edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def __len__(self): 233edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return len(self._obj) 234edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 235edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def __getitem__(self, i): 236edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.acquire() 237edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep try: 238edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return self._obj[i] 239edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep finally: 240edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.release() 241edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 242edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def __setitem__(self, i, value): 243edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.acquire() 244edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep try: 245edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._obj[i] = value 246edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep finally: 247edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.release() 248edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 249edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def __getslice__(self, start, stop): 250edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.acquire() 251edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep try: 252edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep return self._obj[start:stop] 253edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep finally: 254edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.release() 255edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 256edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep def __setslice__(self, start, stop, values): 257edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.acquire() 258edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep try: 259edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self._obj[start:stop] = values 260edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep finally: 261edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep self.release() 262edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 263edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep 264edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoepclass SynchronizedString(SynchronizedArray): 265edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep value = make_property('value') 266edbb763a2b63074cd468a5d33a17908b2cc0654Jeff Vander Stoep raw = make_property('raw') 267