Пример #1
0
 def __init__(self):
     self._global = []
     self._thread_context_lock = ThreadLock()
     self._thread_context = thread_local()
     self._greenlet_context_lock = GreenletRLock()
     self._greenlet_context = greenlet_local()
     self._cache = {}
     self._stackop = get_iterator_next_method(count())
Пример #2
0
 def __init__(self):
     self._global = []
     self._thread_context_lock = ThreadLock()
     self._thread_context = thread_local()
     self._greenlet_context_lock = GreenletRLock()
     self._greenlet_context = greenlet_local()
     self._cache = {}
     self._stackop = get_iterator_next_method(count())
Пример #3
0
class ContextStackManager(object):
    """Helper class for context objects that manages a stack of
    objects.
    """

    def __init__(self):
        self._global = []
        self._thread_context_lock = ThreadLock()
        self._thread_context = thread_local()
        self._greenlet_context_lock = GreenletRLock()
        self._greenlet_context = greenlet_local()
        self._cache = {}
        self._stackop = get_iterator_next_method(count())

    def iter_context_objects(self):
        """Returns an iterator over all objects for the combined
        application and context cache.
        """
        use_gevent = is_gevent_enabled()
        tid = greenlet_get_ident() if use_gevent else thread_get_ident()
        objects = self._cache.get(tid)
        if objects is None:
            if len(self._cache) > _MAX_CONTEXT_OBJECT_CACHE:
                self._cache.clear()
            objects = self._global[:]
            objects.extend(getattr(self._thread_context, 'stack', ()))
            if use_gevent:
                objects.extend(getattr(self._greenlet_context, 'stack', ()))
            objects.sort(reverse=True)
            objects = [x[1] for x in objects]
            self._cache[tid] = objects
        return iter(objects)

    def push_greenlet(self, obj):
        self._greenlet_context_lock.acquire()
        try:
            self._cache.pop(greenlet_get_ident(), None)  # remote chance to conflict with thread ids
            item = (self._stackop(), obj)
            stack = getattr(self._greenlet_context, 'stack', None)
            if stack is None:
                self._greenlet_context.stack = [item]
            else:
                stack.append(item)
        finally:
            self._greenlet_context_lock.release()

    def pop_greenlet(self):
        self._greenlet_context_lock.acquire()
        try:
            self._cache.pop(greenlet_get_ident(), None)  # remote chance to conflict with thread ids
            stack = getattr(self._greenlet_context, 'stack', None)
            assert stack, 'no objects on stack'
            return stack.pop()[1]
        finally:
            self._greenlet_context_lock.release()

    def push_thread(self, obj):
        self._thread_context_lock.acquire()
        try:
            self._cache.pop(thread_get_ident(), None)
            item = (self._stackop(), obj)
            stack = getattr(self._thread_context, 'stack', None)
            if stack is None:
                self._thread_context.stack = [item]
            else:
                stack.append(item)
        finally:
            self._thread_context_lock.release()

    def pop_thread(self):
        self._thread_context_lock.acquire()
        try:
            self._cache.pop(thread_get_ident(), None)
            stack = getattr(self._thread_context, 'stack', None)
            assert stack, 'no objects on stack'
            return stack.pop()[1]
        finally:
            self._thread_context_lock.release()

    def push_application(self, obj):
        self._global.append((self._stackop(), obj))
        self._cache.clear()

    def pop_application(self):
        assert self._global, 'no objects on application stack'
        popped = self._global.pop()[1]
        self._cache.clear()
        return popped
Пример #4
0
class ContextStackManager(object):
    """Helper class for context objects that manages a stack of
    objects.
    """

    def __init__(self):
        self._global = []
        self._thread_context_lock = ThreadLock()
        self._thread_context = thread_local()
        self._greenlet_context_lock = GreenletRLock()
        self._greenlet_context = greenlet_local()
        self._cache = {}
        self._stackop = get_iterator_next_method(count())

    def iter_context_objects(self):
        """Returns an iterator over all objects for the combined
        application and context cache.
        """
        use_gevent = is_gevent_enabled()
        tid = greenlet_get_ident() if use_gevent else thread_get_ident()
        objects = self._cache.get(tid)
        if objects is None:
            if len(self._cache) > _MAX_CONTEXT_OBJECT_CACHE:
                self._cache.clear()
            objects = self._global[:]
            objects.extend(getattr(self._thread_context, 'stack', ()))
            if use_gevent:
                objects.extend(getattr(self._greenlet_context, 'stack', ()))
            objects.sort(reverse=True)
            objects = [x[1] for x in objects]
            self._cache[tid] = objects
        return iter(objects)

    def push_greenlet(self, obj):
        self._greenlet_context_lock.acquire()
        try:
            self._cache.pop(greenlet_get_ident(), None)  # remote chance to conflict with thread ids
            item = (self._stackop(), obj)
            stack = getattr(self._greenlet_context, 'stack', None)
            if stack is None:
                self._greenlet_context.stack = [item]
            else:
                stack.append(item)
        finally:
            self._greenlet_context_lock.release()

    def pop_greenlet(self):
        self._greenlet_context_lock.acquire()
        try:
            self._cache.pop(greenlet_get_ident(), None)  # remote chance to conflict with thread ids
            stack = getattr(self._greenlet_context, 'stack', None)
            assert stack, 'no objects on stack'
            return stack.pop()[1]
        finally:
            self._greenlet_context_lock.release()

    def push_thread(self, obj):
        self._thread_context_lock.acquire()
        try:
            self._cache.pop(thread_get_ident(), None)
            item = (self._stackop(), obj)
            stack = getattr(self._thread_context, 'stack', None)
            if stack is None:
                self._thread_context.stack = [item]
            else:
                stack.append(item)
        finally:
            self._thread_context_lock.release()

    def pop_thread(self):
        self._thread_context_lock.acquire()
        try:
            self._cache.pop(thread_get_ident(), None)
            stack = getattr(self._thread_context, 'stack', None)
            assert stack, 'no objects on stack'
            return stack.pop()[1]
        finally:
            self._thread_context_lock.release()

    def push_application(self, obj):
        self._global.append((self._stackop(), obj))
        self._cache.clear()

    def pop_application(self):
        assert self._global, 'no objects on application stack'
        popped = self._global.pop()[1]
        self._cache.clear()
        return popped