Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 """Posix implementations of platform-specific functionality."""
00018
00019 from __future__ import absolute_import, division, print_function, with_statement
00020
00021 import fcntl
00022 import os
00023
00024 from tornado.platform import interface
00025
00026
00027 def set_close_exec(fd):
00028 flags = fcntl.fcntl(fd, fcntl.F_GETFD)
00029 fcntl.fcntl(fd, fcntl.F_SETFD, flags | fcntl.FD_CLOEXEC)
00030
00031
00032 def _set_nonblocking(fd):
00033 flags = fcntl.fcntl(fd, fcntl.F_GETFL)
00034 fcntl.fcntl(fd, fcntl.F_SETFL, flags | os.O_NONBLOCK)
00035
00036
00037 class Waker(interface.Waker):
00038 def __init__(self):
00039 r, w = os.pipe()
00040 _set_nonblocking(r)
00041 _set_nonblocking(w)
00042 set_close_exec(r)
00043 set_close_exec(w)
00044 self.reader = os.fdopen(r, "rb", 0)
00045 self.writer = os.fdopen(w, "wb", 0)
00046
00047 def fileno(self):
00048 return self.reader.fileno()
00049
00050 def write_fileno(self):
00051 return self.writer.fileno()
00052
00053 def wake(self):
00054 try:
00055 self.writer.write(b"x")
00056 except IOError:
00057 pass
00058
00059 def consume(self):
00060 try:
00061 while True:
00062 result = self.reader.read()
00063 if not result:
00064 break
00065 except IOError:
00066 pass
00067
00068 def close(self):
00069 self.reader.close()
00070 self.writer.close()