Skip to content

Instantly share code, notes, and snippets.

@saghul
Created December 31, 2012 09:30
Show Gist options
  • Select an option

  • Save saghul/4418548 to your computer and use it in GitHub Desktop.

Select an option

Save saghul/4418548 to your computer and use it in GitHub Desktop.
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