Go to the documentation of this file.00001 """Lowest-common-denominator implementations of platform functionality."""
00002 from __future__ import absolute_import, division, with_statement
00003
00004 import errno
00005 import socket
00006
00007 from tornado.platform import interface
00008 from tornado.util import b
00009
00010
00011 class Waker(interface.Waker):
00012 """Create an OS independent asynchronous pipe.
00013
00014 For use on platforms that don't have os.pipe() (or where pipes cannot
00015 be passed to select()), but do have sockets. This includes Windows
00016 and Jython.
00017 """
00018 def __init__(self):
00019
00020
00021 self.writer = socket.socket()
00022
00023
00024 self.writer.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)
00025
00026 count = 0
00027 while 1:
00028 count += 1
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 a = socket.socket()
00040 a.bind(("127.0.0.1", 0))
00041 a.listen(1)
00042 connect_address = a.getsockname()
00043 try:
00044 self.writer.connect(connect_address)
00045 break
00046 except socket.error, detail:
00047 if (not hasattr(errno, 'WSAEADDRINUSE') or
00048 detail[0] != errno.WSAEADDRINUSE):
00049
00050
00051
00052 raise
00053
00054
00055 if count >= 10:
00056 a.close()
00057 self.writer.close()
00058 raise socket.error("Cannot bind trigger!")
00059
00060
00061 a.close()
00062
00063 self.reader, addr = a.accept()
00064 self.reader.setblocking(0)
00065 self.writer.setblocking(0)
00066 a.close()
00067 self.reader_fd = self.reader.fileno()
00068
00069 def fileno(self):
00070 return self.reader.fileno()
00071
00072 def wake(self):
00073 try:
00074 self.writer.send(b("x"))
00075 except (IOError, socket.error):
00076 pass
00077
00078 def consume(self):
00079 try:
00080 while True:
00081 result = self.reader.recv(1024)
00082 if not result:
00083 break
00084 except (IOError, socket.error):
00085 pass
00086
00087 def close(self):
00088 self.reader.close()
00089 self.writer.close()