#!/usr/bin/env python """Utility for forwarding file read events over a zmq socket. This is necessary because select on Windows only supports sockets, not FDs. Authors: * MinRK """ #----------------------------------------------------------------------------- # Copyright (C) 2011 The IPython Development Team # # Distributed under the terms of the BSD License. The full license is in # the file COPYING, distributed as part of this software. #----------------------------------------------------------------------------- #----------------------------------------------------------------------------- # Imports #----------------------------------------------------------------------------- import uuid import zmq from threading import Thread #----------------------------------------------------------------------------- # Code #----------------------------------------------------------------------------- class ForwarderThread(Thread): def __init__(self, sock, fd): Thread.__init__(self) self.daemon=True self.sock = sock self.fd = fd def run(self): """Loop through lines in self.fd, and send them over self.sock.""" line = self.fd.readline() # allow for files opened in unicode mode if isinstance(line, unicode): send = self.sock.send_unicode else: send = self.sock.send while line: send(line) line = self.fd.readline() # line == '' means EOF self.fd.close() self.sock.close() def forward_read_events(fd, context=None): """Forward read events from an FD over a socket. This method wraps a file in a socket pair, so it can be polled for read events by select (specifically zmq.eventloop.ioloop) """ if context is None: context = zmq.Context.instance() push = context.socket(zmq.PUSH) push.setsockopt(zmq.LINGER, -1) pull = context.socket(zmq.PULL) addr='inproc://%s'%uuid.uuid4() push.bind(addr) pull.connect(addr) forwarder = ForwarderThread(push, fd) forwarder.start() return pull __all__ = ['forward_read_events']