-
-
Save saghul/4418548 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import pyuv | |
| import signal | |
| import socket | |
| class SignalWaker(object): | |
| def __init__(self): | |
| # Based on Zope async.py: http://svn.zope.org/zc.ngi/trunk/src/zc/ngi/async.py | |
| self.writer = socket.socket() | |
| # Disable buffering -- pulling the trigger sends 1 byte, | |
| # and we want that sent immediately, to wake up ASAP. | |
| self.writer.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) | |
| count = 0 | |
| while True: | |
| count += 1 | |
| # Bind to a local port; for efficiency, let the OS pick | |
| # a free port for us. | |
| # Unfortunately, stress tests showed that we may not | |
| # be able to connect to that port ("Address already in | |
| # use") despite that the OS picked it. This appears | |
| # to be a race bug in the Windows socket implementation. | |
| # So we loop until a connect() succeeds (almost always | |
| # on the first try). See the long thread at | |
| # http://mail.zope.org/pipermail/zope/2005-July/160433.html | |
| # for hideous details. | |
| a = socket.socket() | |
| a.bind(("127.0.0.1", 0)) | |
| a.listen(1) | |
| connect_address = a.getsockname() | |
| try: | |
| self.writer.connect(connect_address) | |
| except socket.error: | |
| if count >= 10: # I've never seen it go above 2 | |
| a.close() | |
| self.writer.close() | |
| raise socket.error("Cannot bind socket pair") | |
| # Close `a` and try again | |
| a.close() | |
| else: | |
| # success | |
| break | |
| self.reader, addr = a.accept() | |
| self.reader.setblocking(0) | |
| self.writer.setblocking(0) | |
| a.close() | |
| def read_fileno(self): | |
| return self.reader.fileno() | |
| def write_fileno(self): | |
| return self.writer.fileno() | |
| def consume(self): | |
| try: | |
| while True: | |
| result = self.reader.recv(1024) | |
| if not result: | |
| break | |
| except (IOError, socket.error): | |
| pass | |
| def close(self): | |
| self.reader.close() | |
| self.writer.close() | |
| waker = SignalWaker() | |
| signal.set_wakeup_fd(waker.write_fileno()) | |
| def poll_cb(*args): | |
| print "poll_cb" | |
| waker.consume() | |
| def cb(*args): | |
| print "aaaaa" | |
| loop = pyuv.Loop.default_loop() | |
| p = pyuv.Prepare(loop) | |
| p.start(cb) | |
| signal_poller = pyuv.Poll(loop, waker.read_fileno()) | |
| signal_poller.unref() | |
| signal_poller.start(pyuv.UV_READABLE, poll_cb) | |
| loop.run() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment