# Path: evergreen/core/socketpair.py
# class SocketPair(object):
# 
#     def __init__(self):
#         self._reader, self._writer = socketpair()
#         self._reader.setblocking(False)
#         self._writer.setblocking(False)
# 
#     def reader_fileno(self):
#         return self._reader.fileno()
# 
#     def writer_fileno(self):
#         return self._writer.fileno()
# 
#     def close(self):
#         self._reader.close()
#         self._writer.close()
# 
# Path: evergreen/core/threadpool.py
# class ThreadPool(object):
# 
#     def __init__(self, loop):
#         self.loop = loop
# 
#     def spawn(self, func, *args, **kwargs):
#         fut = Future()
#         work = _Work(func, *args, **kwargs)
#         def after(error):
#             if error is not None:
#                 assert error == pyuv.errno.UV_ECANCELLED
#                 return
#             if work.exc is not None:
#                 fut.set_exception(work.exc)
#             else:
#                 fut.set_result(work.result)
#         fut.set_running_or_notify_cancel()
#         self.loop._loop.queue_work(work, after)
#         return fut


import os
import pyuv
import sys
import threading
import traceback
    import signal
    from time import monotonic as _time
    from time import time as _time
from collections import deque
from fibers import Fiber
from functools import partial
from evergreen.core.socketpair import SocketPair
from evergreen.core.threadpool import ThreadPool


class SignalHandler(Handler):

    def __new__(cls, handle, func, *args, **kw):
        obj = Handler.__new__(cls, func, *args, **kw)
        obj._signal_h = handle
        return obj

    def cancel(self):
        super(SignalHandler, self).cancel()
        if self._signal_h and not self._signal_h.closed:
            loop = self._signal_h.loop.event_loop
            self._signal_h.close()
            loop._signals[self._signal_h.signum].discard(self._signal_h)
        self._signal_h = None


RUN_DEFAULT = 1
RUN_FOREVER = 2

class EventLoop(object):

    def __init__(self):
        if getattr(_tls, 'loop', None) is not None:
            raise RuntimeError('cannot instantiate more than one event loop per thread')
        _tls.loop = self
        self._loop = pyuv.Loop()
        self._loop.excepthook = self._handle_error
        self._loop.event_loop = self

# Path: evergreen/core/socketpair.py
# class SocketPair(object):
# 
#     def __init__(self):
#         self._reader, self._writer = socketpair()
#         self._reader.setblocking(False)
#         self._writer.setblocking(False)
# 
#     def reader_fileno(self):
#         return self._reader.fileno()
# 
#     def writer_fileno(self):
#         return self._writer.fileno()
# 
#     def close(self):
#         self._reader.close()
#         self._writer.close()
# 
# Path: evergreen/core/threadpool.py
# class ThreadPool(object):
# 
#     def __init__(self, loop):
#         self.loop = loop
# 
#     def spawn(self, func, *args, **kwargs):
#         fut = Future()
#         work = _Work(func, *args, **kwargs)
#         def after(error):
#             if error is not None:
#                 assert error == pyuv.errno.UV_ECANCELLED
#                 return
#             if work.exc is not None:
#                 fut.set_exception(work.exc)
#             else:
#                 fut.set_result(work.result)
#         fut.set_running_or_notify_cancel()
#         self.loop._loop.queue_work(work, after)
#         return fut


# Path: evergreen/core/loop.py
import os
import pyuv
import sys
import threading
import traceback
    import signal
    from time import monotonic as _time
    from time import time as _time
from collections import deque
from fibers import Fiber
from functools import partial
from evergreen.core.socketpair import SocketPair
from evergreen.core.threadpool import ThreadPool



class SignalHandler(Handler):

    def __new__(cls, handle, func, *args, **kw):
        obj = Handler.__new__(cls, func, *args, **kw)
        obj._signal_h = handle
        return obj

    def cancel(self):
        super(SignalHandler, self).cancel()
        if self._signal_h and not self._signal_h.closed:
            loop = self._signal_h.loop.event_loop
            self._signal_h.close()
            loop._signals[self._signal_h.signum].discard(self._signal_h)
        self._signal_h = None


RUN_DEFAULT = 1
RUN_FOREVER = 2

class EventLoop(object):

    def __init__(self):
        if getattr(_tls, 'loop', None) is not None:
            raise RuntimeError('cannot instantiate more than one event loop per thread')
        _tls.loop = self
        self._loop = pyuv.Loop()
        self._loop.excepthook = self._handle_error
        self._loop.event_loop = self

        self._threadpool = ThreadPool(self)