# Path: evergreen/event.py
# class Event(object):
# 
#     def __init__(self):
#         self._cond = Condition(Lock())
#         self._flag = False
# 
#     def is_set(self):
#         return self._flag
# 
#     def set(self):
#         self._cond.acquire()
#         try:
#             self._flag = True
#             self._cond.notify_all()
#         finally:
#             self._cond.release()
# 
#     def clear(self):
#         self._cond.acquire()
#         try:
#             self._flag = False
#         finally:
#             self._cond.release()
# 
#     def wait(self, timeout=None):
#         self._cond.acquire()
#         try:
#             signaled = self._flag
#             if not signaled:
#                 signaled = self._cond.wait(timeout)
#             return signaled
#         finally:
#             self._cond.release()
# 
# Path: evergreen/futures/_base.py
# class Future(object):
# 
#     def __init__(self):
#         self._condition = Condition()
#         self._state = PENDING
#         self._result = None
#         self._exception = None
#         self._callbacks = []
#         self._waiters = []
# 
#     def __repr__(self):
#         with self._condition:
#             if self._state == FINISHED:
#                 if self._exception:
#                     text = 'raised %s' % self._exception.__class__.__name__
#                 else:
#                     text = 'returned %s' % self._result.__class__.__name__
#                 return '<%s at %s state=%s %s>' % (
#                     self.__class__.__name__,
#                     hex(id(self)),
#                     _STATE_TO_DESCRIPTION_MAP[self._state],
#                     text)
#             return '<%s at %s state=%s>' % (
#                     self.__class__.__name__,
#                     hex(id(self)),
#                    _STATE_TO_DESCRIPTION_MAP[self._state])
# 
#     def cancel(self):
#         with self._condition:
#             if self._state in (RUNNING, FINISHED):
#                 return False
#             elif self._state in (CANCELLED, CANCELLED_AND_NOTIFIED):
#                 return True
#             self._state = CANCELLED
#             self._condition.notify_all()
#         self._run_callbacks()
#         return True
# 
#     @property
#     def cancelled(self):
#         with self._condition:
#             return self._state in (CANCELLED, CANCELLED_AND_NOTIFIED)
# 
#     @property
#     def done(self):
#         with self._condition:
#             return self._state in (CANCELLED, CANCELLED_AND_NOTIFIED, FINISHED)
# 
#     def get(self, timeout=None, return_exception=False):
#         with self._condition:
#             if self._state in (CANCELLED, CANCELLED_AND_NOTIFIED):
#                 raise CancelledError()
#             elif self._state == FINISHED:
#                 return self._get_result(return_exception)
# 
#             self._condition.wait(timeout)
# 
#             if self._state in (CANCELLED, CANCELLED_AND_NOTIFIED):
#                 raise CancelledError()
#             elif self._state == FINISHED:
#                 return self._get_result(return_exception)
#             else:
#                 raise TimeoutError()
# 
#     def add_done_callback(self, func):
#         with self._condition:
#             if self._state not in (CANCELLED, CANCELLED_AND_NOTIFIED, FINISHED):
#                 self._callbacks.append(func)
#                 return
#         func(self)
# 
#     # Internal
# 
#     def _get_result(self, return_exception):
#         if self._exception:
#             if return_exception:
#                 return self._exception
#             else:
#                 raise self._exception
#         else:
#             return self._result
# 
#     def _run_callbacks(self):
#         for cb in self._callbacks:
#             try:
#                 cb(self)
#             except Exception:
#                 log.exception('exception calling callback for %r', self)
#         self._callbacks = []
# 
#     def set_running_or_notify_cancel(self):
#         with self._condition:
#             if self._state == CANCELLED:
#                 self._state = CANCELLED_AND_NOTIFIED
#                 for waiter in self._waiters:
#                     waiter.add_cancelled(self)
#                 # self._condition.notify_all() is not necessary because
#                 # self.cancel() triggers a notification.
#                 return False
#             elif self._state == PENDING:
#                 self._state = RUNNING
#                 return True
#             else:
#                 raise RuntimeError('Future in unexpected state: %s' % self._state)
# 
#     def set_result(self, result):
#         with self._condition:
#             self._result = result
#             self._state = FINISHED
#             for waiter in self._waiters:
#                 waiter.add_result(self)
#             self._condition.notify_all()
#         self._run_callbacks()
# 
#     def set_exception(self, exception):
#         with self._condition:
#             self._exception = exception
#             self._state = FINISHED
#             for waiter in self._waiters:
#                 waiter.add_exception(self)
#             self._condition.notify_all()
#         self._run_callbacks()


import pyuv
import sys
from evergreen.event import Event
from evergreen.futures import Future

"""Internal thread pool which uses the pyuv work queuing capability. This module
is for internal use of Evergreen.
"""


class _Work(object):
    __slots__ = ('func', 'args', 'kwargs', 'result', 'exc')

    def __init__(self, func, *args, **kwargs):
        self.func = func
        self.args = args
        self.kwargs = kwargs
        self.result = None
        self.exc = None

    def __call__(self):
        try:
            self.result = self.func(*self.args, **self.kwargs)
        except BaseException:
            self.exc = sys.exc_info()
        self = None


class ThreadPool(object):

    def __init__(self, loop):
        self.loop = loop

    def spawn(self, func, *args, **kwargs):

# Path: evergreen/event.py
# class Event(object):
# 
#     def __init__(self):
#         self._cond = Condition(Lock())
#         self._flag = False
# 
#     def is_set(self):
#         return self._flag
# 
#     def set(self):
#         self._cond.acquire()
#         try:
#             self._flag = True
#             self._cond.notify_all()
#         finally:
#             self._cond.release()
# 
#     def clear(self):
#         self._cond.acquire()
#         try:
#             self._flag = False
#         finally:
#             self._cond.release()
# 
#     def wait(self, timeout=None):
#         self._cond.acquire()
#         try:
#             signaled = self._flag
#             if not signaled:
#                 signaled = self._cond.wait(timeout)
#             return signaled
#         finally:
#             self._cond.release()
# 
# Path: evergreen/futures/_base.py
# class Future(object):
# 
#     def __init__(self):
#         self._condition = Condition()
#         self._state = PENDING
#         self._result = None
#         self._exception = None
#         self._callbacks = []
#         self._waiters = []
# 
#     def __repr__(self):
#         with self._condition:
#             if self._state == FINISHED:
#                 if self._exception:
#                     text = 'raised %s' % self._exception.__class__.__name__
#                 else:
#                     text = 'returned %s' % self._result.__class__.__name__
#                 return '<%s at %s state=%s %s>' % (
#                     self.__class__.__name__,
#                     hex(id(self)),
#                     _STATE_TO_DESCRIPTION_MAP[self._state],
#                     text)
#             return '<%s at %s state=%s>' % (
#                     self.__class__.__name__,
#                     hex(id(self)),
#                    _STATE_TO_DESCRIPTION_MAP[self._state])
# 
#     def cancel(self):
#         with self._condition:
#             if self._state in (RUNNING, FINISHED):
#                 return False
#             elif self._state in (CANCELLED, CANCELLED_AND_NOTIFIED):
#                 return True
#             self._state = CANCELLED
#             self._condition.notify_all()
#         self._run_callbacks()
#         return True
# 
#     @property
#     def cancelled(self):
#         with self._condition:
#             return self._state in (CANCELLED, CANCELLED_AND_NOTIFIED)
# 
#     @property
#     def done(self):
#         with self._condition:
#             return self._state in (CANCELLED, CANCELLED_AND_NOTIFIED, FINISHED)
# 
#     def get(self, timeout=None, return_exception=False):
#         with self._condition:
#             if self._state in (CANCELLED, CANCELLED_AND_NOTIFIED):
#                 raise CancelledError()
#             elif self._state == FINISHED:
#                 return self._get_result(return_exception)
# 
#             self._condition.wait(timeout)
# 
#             if self._state in (CANCELLED, CANCELLED_AND_NOTIFIED):
#                 raise CancelledError()
#             elif self._state == FINISHED:
#                 return self._get_result(return_exception)
#             else:
#                 raise TimeoutError()
# 
#     def add_done_callback(self, func):
#         with self._condition:
#             if self._state not in (CANCELLED, CANCELLED_AND_NOTIFIED, FINISHED):
#                 self._callbacks.append(func)
#                 return
#         func(self)
# 
#     # Internal
# 
#     def _get_result(self, return_exception):
#         if self._exception:
#             if return_exception:
#                 return self._exception
#             else:
#                 raise self._exception
#         else:
#             return self._result
# 
#     def _run_callbacks(self):
#         for cb in self._callbacks:
#             try:
#                 cb(self)
#             except Exception:
#                 log.exception('exception calling callback for %r', self)
#         self._callbacks = []
# 
#     def set_running_or_notify_cancel(self):
#         with self._condition:
#             if self._state == CANCELLED:
#                 self._state = CANCELLED_AND_NOTIFIED
#                 for waiter in self._waiters:
#                     waiter.add_cancelled(self)
#                 # self._condition.notify_all() is not necessary because
#                 # self.cancel() triggers a notification.
#                 return False
#             elif self._state == PENDING:
#                 self._state = RUNNING
#                 return True
#             else:
#                 raise RuntimeError('Future in unexpected state: %s' % self._state)
# 
#     def set_result(self, result):
#         with self._condition:
#             self._result = result
#             self._state = FINISHED
#             for waiter in self._waiters:
#                 waiter.add_result(self)
#             self._condition.notify_all()
#         self._run_callbacks()
# 
#     def set_exception(self, exception):
#         with self._condition:
#             self._exception = exception
#             self._state = FINISHED
#             for waiter in self._waiters:
#                 waiter.add_exception(self)
#             self._condition.notify_all()
#         self._run_callbacks()


# Path: evergreen/core/threadpool.py
import pyuv
import sys
from evergreen.event import Event
from evergreen.futures import Future


"""Internal thread pool which uses the pyuv work queuing capability. This module
is for internal use of Evergreen.
"""


class _Work(object):
    __slots__ = ('func', 'args', 'kwargs', 'result', 'exc')

    def __init__(self, func, *args, **kwargs):
        self.func = func
        self.args = args
        self.kwargs = kwargs
        self.result = None
        self.exc = None

    def __call__(self):
        try:
            self.result = self.func(*self.args, **self.kwargs)
        except BaseException:
            self.exc = sys.exc_info()
        self = None


class ThreadPool(object):

    def __init__(self, loop):
        self.loop = loop

    def spawn(self, func, *args, **kwargs):

        fut = Future()