# -*- coding: utf-8 -*-
# Moovida - Home multimedia server
# Copyright (C) 2006-2009 Fluendo Embedded S.L. (www.fluendo.com).
# All rights reserved.
#
# This file is available under one of two license agreements.
#
# This file is licensed under the GPL version 3.
# See "LICENSE.GPL" in the root of this distribution including a special
# exception to use Moovida with Fluendo's plugins.
#
# The GPL part of Moovida is also available under a commercial licensing
# agreement from Fluendo.
# See "LICENSE.Moovida" in the root directory of this distribution package
# for details on that license.

__maintainer__ = 'Lionel Martin <lionel@fluendo.com>'
__maintainer2__ = 'Florian Boucault <florian@fluendo.com>'

import threading

class ThreadsafeList(list):
    """
    Thread-safe subclass of the built-in type list.
    """
    
    def __init__(self, *args, **kw):
        self._lock = threading.Lock()
        list.__init__(self, *args, **kw)

    def __eq__(self, other):
        try:
            self._lock.acquire()
            r = (self == other)
        finally:
            self._lock.release()
        return r

    def __len__(self):
        try:
            self._lock.acquire()
            r = list.__len__(self)
        finally:
            self._lock.release()
        return r

    def __getitem__(self, rank):
        try:
            self._lock.acquire()
            r = list.__getitem__(self, rank)
        finally:
            self._lock.release()
        return r

    def __setitem__(self, rank, value):
        try:
            self._lock.acquire()
            list.__setitem__(self, rank, value)
        finally:
            self._lock.release()

    def __delitem__(self, rank):
        try:
            self._lock.acquire()
            list.__delitem__(self, rank)
        finally:
            self._lock.release()

    def __iter__(self):
        # The returned iterator is not thread-safe itself
        # http://mail.python.org/pipermail/python-list/2005-April/315764.html
        # has interesting ideas.
        try:
            self._lock.acquire()
            r = list.__iter__(self)
        finally:
            self._lock.release()
        return r

    def __contains__(self, item):
        try:
            self._lock.acquire()
            r = list.__contains__(self, item)
        finally:
            self._lock.release()
        return r

    def append(self, element):
        try:
            self._lock.acquire()
            list.append(self, element)
        finally:
            self._lock.release()

    def count(self, element):
        try:
            self._lock.acquire()
            r = list.count(self, element)
        finally:
            self._lock.release()
        return r

    def index(self, element):
        try:
            self._lock.acquire()
            r = list.index(self, element)
        finally:
            self._lock.release()
        return r

    def extend(self, elements):
        try:
            self._lock.acquire()
            list.extend(self, elements)
        finally:
            self._lock.release()

    def insert(self, position, element):
        try:
            self._lock.acquire()
            list.insert(self, position, element)
        finally:
            self._lock.release()

    def pop(self, position=-1):
        try:
            self._lock.acquire()
            r = list.pop(self, position)
        finally:
            self._lock.release()
        return r

    def remove(self, element):
        try:
            self._lock.acquire()
            list.remove(self, element)
        finally:
            self._lock.release()

    def reverse(self):
        try:
            self._lock.acquire()
            list.reverse(self)
        finally:
            self._lock.release()

    def sort(self, key=None):
        try:
            self._lock.acquire()
            list.sort(self,key=key)
        finally:
            self._lock.release()

    def __add__(self, operand):
        try:
            self._lock.acquire()
            r = list.__add__(self, operand)
        finally:
            self._lock.release()
        return r

    def __iadd__(self, operand):
        try:
            self._lock.acquire()
            r = list.__iadd__(self, operand)
        finally:
            self._lock.release()
        return r

    def __mul__(self, coefficient):
        try:
            self._lock.acquire()
            r = list.__mul__(self, coefficient)
        finally:
            self._lock.release()
        return r

    def __imul__(self, coefficient):
        try:
            self._lock.acquire()
            r = list.__imul__(self, coefficient)
        finally:
            self._lock.release()
        return r

    def __getslice__(self, i, j):
        try:
            self._lock.acquire()
            r = list.__getslice__(self, i, j)
        finally:
            self._lock.release()
        return r

    def __setslice__(self, i, j, sequence):
        try:
            self._lock.acquire()
            list.__setslice__(self, i, j, sequence)
        finally:
            self._lock.release()

    def __delslice__(self, i, j):
        try:
            self._lock.acquire()
            list.__delslice__(self, i, j)
        finally:
            self._lock.release()

    def __copy__(self):
        # this method is a bit hard to implement
        raise NotImplementedError

    def __deepcopy__(self, memento):
        # this method is a bit hard to implement
        raise NotImplementedError
