# Path: zorro/core.py
# def gethub():
#     let = greenlet.getcurrent()
#     return let.hub
# 
# class Lock(Condition):
#     def __init__(self):
#         super().__init__()
#         self._locked = False
# 
#     def acquire(self):
#         while self._locked:
#             self.wait()
#         self._locked = True
# 
#     def release(self):
#         self._locked = False
#         self.notify()
# 
#     def __enter__(self):
#         self.acquire()
# 
#     def __exit__(self, exc_type, exc_value, exc_tb):
#         self.release()
# 
# class Future(object):
#     def __init__(self, fun=None):
#         self._listeners = []
#         self._value = FUTURE_PENDING
#         if fun is not None:
#             def future():
#                 try:
#                     result = fun()
#                 except Exception as e:
#                     self.throw(e)
#                 else:
#                     self.set(result)
#             gethub().do_spawn(future)
# 
#     def get(self, timeout=None):
#         val = self._value
#         if val is not FUTURE_PENDING:
#             if val is FUTURE_EXCEPTION:
#                 raise self._exception
#             else:
#                 return val
#         cur = greenlet.getcurrent()
#         cur.cleanup.append(self._listeners.remove)
#         self._listeners.append(cur)
#         hub = cur.hub
#         if timeout is not None:
#             targ = time.time() + timeout
#             cur.cleanup.append(hub._timeouts.add(targ, cur))
#         del cur # no cycles
#         hub._self.switch()
#         val = self._value
#         if val is FUTURE_PENDING:
#             raise TimeoutError()
#         if val is FUTURE_EXCEPTION:
#             raise self._exception
#         else:
#             return val
# 
#     def set(self, value):
#         if self._value is not FUTURE_PENDING:
#             raise RuntimeError("Value is already set")
#         self._value = value
#         lst = self._listeners
#         del self._listeners
#         hub = gethub()
#         for one in lst:
#             hub.queue_task(one)
# 
#     def throw(self, exception):
#         self._value = FUTURE_EXCEPTION
#         self._exception = exception
#         lst = self._listeners
#         del self._listeners
#         for one in lst:
#             gethub().queue_task(one)
# 
#     def check(self):
#         return self._value is FUTURE_PENDING
# 
# Path: zorro/channel.py
# class PipelinedReqChannel(BaseChannel):
# 
#     def __init__(self):
#         super().__init__()
#         self._producing = deque()
#         self._cur_producing = []
# 
#     def _stop_producing(self):
#         prod = self._producing
#         del self._producing
#         for num, fut in prod:
#             fut.throw(PipeError())
#         self._cond.notify()  # wake up consumer if it waits for messages
# 
#     def produce(self, value):
#         if not self._alive:
#             raise ShutdownException()
#         val = self._cur_producing.append(value)
#         num = self._producing[0][0]
#         if num is None:
#             del self._cur_producing[:]
#             self._producing.popleft()[1].set(value)
#         elif len(self._cur_producing) >= num:
#             res = tuple(self._cur_producing)
#             del self._cur_producing[:]
#             self._producing.popleft()[1].set(res)
#         else:
#             return
# 
#     def request(self, input, num_output=None):
#         if not self._alive:
#             raise PipeError()
#         val = Future()
#         self._pending.append(input)
#         self._producing.append((num_output, val))
#         self._cond.notify()
#         return val
# 
#     def push(self, input):
#         """For requests which do not need an answer"""
#         self._pending.append(input)
#         self._cond.notify()


import socket
import errno
from time import time as current_time
from .core import gethub, Lock, Future
from .channel import PipelinedReqChannel



class Unix(PipelinedReqChannel):
    BUFSIZE = 1024

    def __init__(self, unixsock='/var/run/collectd-unixsock'):
        self._sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
        self._sock.setblocking(0)
        self._cur_producing = []
        self._todo = 0
        try:
            self._sock.connect(unixsock)
        except socket.error as e:
            if e.errno == errno.EINPROGRESS:

# Path: zorro/core.py
# def gethub():
#     let = greenlet.getcurrent()
#     return let.hub
# 
# class Lock(Condition):
#     def __init__(self):
#         super().__init__()
#         self._locked = False
# 
#     def acquire(self):
#         while self._locked:
#             self.wait()
#         self._locked = True
# 
#     def release(self):
#         self._locked = False
#         self.notify()
# 
#     def __enter__(self):
#         self.acquire()
# 
#     def __exit__(self, exc_type, exc_value, exc_tb):
#         self.release()
# 
# class Future(object):
#     def __init__(self, fun=None):
#         self._listeners = []
#         self._value = FUTURE_PENDING
#         if fun is not None:
#             def future():
#                 try:
#                     result = fun()
#                 except Exception as e:
#                     self.throw(e)
#                 else:
#                     self.set(result)
#             gethub().do_spawn(future)
# 
#     def get(self, timeout=None):
#         val = self._value
#         if val is not FUTURE_PENDING:
#             if val is FUTURE_EXCEPTION:
#                 raise self._exception
#             else:
#                 return val
#         cur = greenlet.getcurrent()
#         cur.cleanup.append(self._listeners.remove)
#         self._listeners.append(cur)
#         hub = cur.hub
#         if timeout is not None:
#             targ = time.time() + timeout
#             cur.cleanup.append(hub._timeouts.add(targ, cur))
#         del cur # no cycles
#         hub._self.switch()
#         val = self._value
#         if val is FUTURE_PENDING:
#             raise TimeoutError()
#         if val is FUTURE_EXCEPTION:
#             raise self._exception
#         else:
#             return val
# 
#     def set(self, value):
#         if self._value is not FUTURE_PENDING:
#             raise RuntimeError("Value is already set")
#         self._value = value
#         lst = self._listeners
#         del self._listeners
#         hub = gethub()
#         for one in lst:
#             hub.queue_task(one)
# 
#     def throw(self, exception):
#         self._value = FUTURE_EXCEPTION
#         self._exception = exception
#         lst = self._listeners
#         del self._listeners
#         for one in lst:
#             gethub().queue_task(one)
# 
#     def check(self):
#         return self._value is FUTURE_PENDING
# 
# Path: zorro/channel.py
# class PipelinedReqChannel(BaseChannel):
# 
#     def __init__(self):
#         super().__init__()
#         self._producing = deque()
#         self._cur_producing = []
# 
#     def _stop_producing(self):
#         prod = self._producing
#         del self._producing
#         for num, fut in prod:
#             fut.throw(PipeError())
#         self._cond.notify()  # wake up consumer if it waits for messages
# 
#     def produce(self, value):
#         if not self._alive:
#             raise ShutdownException()
#         val = self._cur_producing.append(value)
#         num = self._producing[0][0]
#         if num is None:
#             del self._cur_producing[:]
#             self._producing.popleft()[1].set(value)
#         elif len(self._cur_producing) >= num:
#             res = tuple(self._cur_producing)
#             del self._cur_producing[:]
#             self._producing.popleft()[1].set(res)
#         else:
#             return
# 
#     def request(self, input, num_output=None):
#         if not self._alive:
#             raise PipeError()
#         val = Future()
#         self._pending.append(input)
#         self._producing.append((num_output, val))
#         self._cond.notify()
#         return val
# 
#     def push(self, input):
#         """For requests which do not need an answer"""
#         self._pending.append(input)
#         self._cond.notify()


# Path: zorro/collectd.py
import socket
import errno
from time import time as current_time
from .core import gethub, Lock, Future
from .channel import PipelinedReqChannel




class Unix(PipelinedReqChannel):
    BUFSIZE = 1024

    def __init__(self, unixsock='/var/run/collectd-unixsock'):
        self._sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
        self._sock.setblocking(0)
        self._cur_producing = []
        self._todo = 0
        try:
            self._sock.connect(unixsock)
        except socket.error as e:
            if e.errno == errno.EINPROGRESS:

                gethub().do_write(self._sock)