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, with_statement
00020 
00021 import fcntl
00022 import os
00023 
00024 from tornado.platform import interface
00025 from tornado.util import b
00026 
00027 
00028 def set_close_exec(fd):
00029     flags = fcntl.fcntl(fd, fcntl.F_GETFD)
00030     fcntl.fcntl(fd, fcntl.F_SETFD, flags | fcntl.FD_CLOEXEC)
00031 
00032 
00033 def _set_nonblocking(fd):
00034     flags = fcntl.fcntl(fd, fcntl.F_GETFL)
00035     fcntl.fcntl(fd, fcntl.F_SETFL, flags | os.O_NONBLOCK)
00036 
00037 
00038 class Waker(interface.Waker):
00039     def __init__(self):
00040         r, w = os.pipe()
00041         _set_nonblocking(r)
00042         _set_nonblocking(w)
00043         set_close_exec(r)
00044         set_close_exec(w)
00045         self.reader = os.fdopen(r, "rb", 0)
00046         self.writer = os.fdopen(w, "wb", 0)
00047 
00048     def fileno(self):
00049         return self.reader.fileno()
00050 
00051     def wake(self):
00052         try:
00053             self.writer.write(b("x"))
00054         except IOError:
00055             pass
00056 
00057     def consume(self):
00058         try:
00059             while True:
00060                 result = self.reader.read()
00061                 if not result:
00062                     break
00063         except IOError:
00064             pass
00065 
00066     def close(self):
00067         self.reader.close()
00068         self.writer.close()