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