Go to the documentation of this file.00001 """Lowest-common-denominator implementations of platform functionality."""
00002 from __future__ import absolute_import, division, print_function, with_statement
00003
00004 import errno
00005 import socket
00006
00007 from tornado.platform import interface
00008
00009
00010 class Waker(interface.Waker):
00011 """Create an OS independent asynchronous pipe.
00012
00013 For use on platforms that don't have os.pipe() (or where pipes cannot
00014 be passed to select()), but do have sockets. This includes Windows
00015 and Jython.
00016 """
00017 def __init__(self):
00018
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 as 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 write_fileno(self):
00073 return self.writer.fileno()
00074
00075 def wake(self):
00076 try:
00077 self.writer.send(b"x")
00078 except (IOError, socket.error):
00079 pass
00080
00081 def consume(self):
00082 try:
00083 while True:
00084 result = self.reader.recv(1024)
00085 if not result:
00086 break
00087 except (IOError, socket.error):
00088 pass
00089
00090 def close(self):
00091 self.reader.close()
00092 self.writer.close()