14adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# 24adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# Module which supports allocation of ctypes objects from shared memory 34adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# 44adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# multiprocessing/sharedctypes.py 54adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# 64adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# Copyright (c) 2006-2008, R Oudkerk 74adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# All rights reserved. 84adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# 94adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# Redistribution and use in source and binary forms, with or without 104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# modification, are permitted provided that the following conditions 114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# are met: 124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# 134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# 1. Redistributions of source code must retain the above copyright 144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# notice, this list of conditions and the following disclaimer. 154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# 2. Redistributions in binary form must reproduce the above copyright 164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# notice, this list of conditions and the following disclaimer in the 174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# documentation and/or other materials provided with the distribution. 184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# 3. Neither the name of author nor the names of any contributors may be 194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# used to endorse or promote products derived from this software 204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# without specific prior written permission. 214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# 224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND 234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# SUCH DAMAGE. 334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# 344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoimport sys 364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoimport ctypes 374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoimport weakref 384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaofrom multiprocessing import heap, RLock 404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaofrom multiprocessing.forking import assert_spawning, ForkingPickler 414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao__all__ = ['RawValue', 'RawArray', 'Value', 'Array', 'copy', 'synchronized'] 434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# 454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# 464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# 474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaotypecode_to_type = { 494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 'c': ctypes.c_char, 'u': ctypes.c_wchar, 504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 'b': ctypes.c_byte, 'B': ctypes.c_ubyte, 514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 'h': ctypes.c_short, 'H': ctypes.c_ushort, 524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 'i': ctypes.c_int, 'I': ctypes.c_uint, 534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 'l': ctypes.c_long, 'L': ctypes.c_ulong, 544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 'f': ctypes.c_float, 'd': ctypes.c_double 554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao } 564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# 584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# 594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# 604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaodef _new_value(type_): 624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao size = ctypes.sizeof(type_) 634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao wrapper = heap.BufferWrapper(size) 644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return rebuild_ctype(type_, wrapper, None) 654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaodef RawValue(typecode_or_type, *args): 674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ''' 684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao Returns a ctypes object allocated from shared memory 694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ''' 704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao type_ = typecode_to_type.get(typecode_or_type, typecode_or_type) 714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao obj = _new_value(type_) 724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ctypes.memset(ctypes.addressof(obj), 0, ctypes.sizeof(obj)) 734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao obj.__init__(*args) 744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return obj 754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaodef RawArray(typecode_or_type, size_or_initializer): 774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ''' 784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao Returns a ctypes array allocated from shared memory 794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ''' 804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao type_ = typecode_to_type.get(typecode_or_type, typecode_or_type) 814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if isinstance(size_or_initializer, (int, long)): 824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao type_ = type_ * size_or_initializer 834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao obj = _new_value(type_) 844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ctypes.memset(ctypes.addressof(obj), 0, ctypes.sizeof(obj)) 854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return obj 864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao else: 874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao type_ = type_ * len(size_or_initializer) 884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao result = _new_value(type_) 894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao result.__init__(*size_or_initializer) 904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return result 914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaodef Value(typecode_or_type, *args, **kwds): 934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ''' 944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao Return a synchronization wrapper for a Value 954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ''' 964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao lock = kwds.pop('lock', None) 974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if kwds: 984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao raise ValueError('unrecognized keyword argument(s): %s' % kwds.keys()) 994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao obj = RawValue(typecode_or_type, *args) 1004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if lock is False: 1014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return obj 1024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if lock in (True, None): 1034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao lock = RLock() 1044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if not hasattr(lock, 'acquire'): 1054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao raise AttributeError("'%r' has no method 'acquire'" % lock) 1064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return synchronized(obj, lock) 1074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaodef Array(typecode_or_type, size_or_initializer, **kwds): 1094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ''' 1104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao Return a synchronization wrapper for a RawArray 1114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ''' 1124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao lock = kwds.pop('lock', None) 1134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if kwds: 1144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao raise ValueError('unrecognized keyword argument(s): %s' % kwds.keys()) 1154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao obj = RawArray(typecode_or_type, size_or_initializer) 1164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if lock is False: 1174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return obj 1184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if lock in (True, None): 1194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao lock = RLock() 1204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if not hasattr(lock, 'acquire'): 1214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao raise AttributeError("'%r' has no method 'acquire'" % lock) 1224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return synchronized(obj, lock) 1234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaodef copy(obj): 1254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao new_obj = _new_value(type(obj)) 1264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ctypes.pointer(new_obj)[0] = obj 1274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return new_obj 1284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaodef synchronized(obj, lock=None): 1304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao assert not isinstance(obj, SynchronizedBase), 'object already synchronized' 1314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if isinstance(obj, ctypes._SimpleCData): 1334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return Synchronized(obj, lock) 1344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao elif isinstance(obj, ctypes.Array): 1354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if obj._type_ is ctypes.c_char: 1364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return SynchronizedString(obj, lock) 1374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return SynchronizedArray(obj, lock) 1384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao else: 1394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao cls = type(obj) 1404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao try: 1414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao scls = class_cache[cls] 1424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao except KeyError: 1434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao names = [field[0] for field in cls._fields_] 1444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao d = dict((name, make_property(name)) for name in names) 1454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao classname = 'Synchronized' + cls.__name__ 1464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao scls = class_cache[cls] = type(classname, (SynchronizedBase,), d) 1474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return scls(obj, lock) 1484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# 1504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# Functions for pickling/unpickling 1514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# 1524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaodef reduce_ctype(obj): 1544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao assert_spawning(obj) 1554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if isinstance(obj, ctypes.Array): 1564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return rebuild_ctype, (obj._type_, obj._wrapper, obj._length_) 1574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao else: 1584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return rebuild_ctype, (type(obj), obj._wrapper, None) 1594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaodef rebuild_ctype(type_, wrapper, length): 1614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao if length is not None: 1624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao type_ = type_ * length 1634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao ForkingPickler.register(type_, reduce_ctype) 1644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao obj = type_.from_address(wrapper.get_address()) 1654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao obj._wrapper = wrapper 1664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return obj 1674adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1684adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# 1694adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# Function to create properties 1704adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# 1714adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1724adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaodef make_property(name): 1734adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao try: 1744adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return prop_cache[name] 1754adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao except KeyError: 1764adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao d = {} 1774adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao exec template % ((name,)*7) in d 1784adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao prop_cache[name] = d[name] 1794adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return d[name] 1804adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1814adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaotemplate = ''' 1824adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaodef get%s(self): 1834adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.acquire() 1844adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao try: 1854adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return self._obj.%s 1864adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao finally: 1874adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.release() 1884adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaodef set%s(self, value): 1894adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.acquire() 1904adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao try: 1914adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self._obj.%s = value 1924adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao finally: 1934adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.release() 1944adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao%s = property(get%s, set%s) 1954adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao''' 1964adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 1974adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoprop_cache = {} 1984adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass_cache = weakref.WeakKeyDictionary() 1994adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2004adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# 2014adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# Synchronized wrappers 2024adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao# 2034adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2044adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass SynchronizedBase(object): 2054adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2064adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def __init__(self, obj, lock=None): 2074adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self._obj = obj 2084adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self._lock = lock or RLock() 2094adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.acquire = self._lock.acquire 2104adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.release = self._lock.release 2114adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2124adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def __reduce__(self): 2134adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao assert_spawning(self) 2144adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return synchronized, (self._obj, self._lock) 2154adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2164adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def get_obj(self): 2174adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return self._obj 2184adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2194adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def get_lock(self): 2204adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return self._lock 2214adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2224adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def __repr__(self): 2234adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return '<%s wrapper for %s>' % (type(self).__name__, self._obj) 2244adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2254adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2264adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass Synchronized(SynchronizedBase): 2274adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao value = make_property('value') 2284adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2294adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2304adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass SynchronizedArray(SynchronizedBase): 2314adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2324adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def __len__(self): 2334adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return len(self._obj) 2344adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2354adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def __getitem__(self, i): 2364adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.acquire() 2374adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao try: 2384adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return self._obj[i] 2394adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao finally: 2404adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.release() 2414adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2424adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def __setitem__(self, i, value): 2434adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.acquire() 2444adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao try: 2454adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self._obj[i] = value 2464adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao finally: 2474adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.release() 2484adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2494adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def __getslice__(self, start, stop): 2504adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.acquire() 2514adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao try: 2524adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao return self._obj[start:stop] 2534adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao finally: 2544adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.release() 2554adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2564adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao def __setslice__(self, start, stop, values): 2574adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.acquire() 2584adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao try: 2594adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self._obj[start:stop] = values 2604adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao finally: 2614adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao self.release() 2624adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2634adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao 2644adfde8bc82dd39f59e0445588c3e599ada477dJosh Gaoclass SynchronizedString(SynchronizedArray): 2654adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao value = make_property('value') 2664adfde8bc82dd39f59e0445588c3e599ada477dJosh Gao raw = make_property('raw') 267