posix.py revision 781d71db
1#!/usr/bin/env python
2#
3# Copyright 2011 Facebook
4#
5# Licensed under the Apache License, Version 2.0 (the "License"); you may
6# not use this file except in compliance with the License. You may obtain
7# a copy of the License at
8#
9#     http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14# License for the specific language governing permissions and limitations
15# under the License.
16
17"""Posix implementations of platform-specific functionality."""
18
19from __future__ import absolute_import, division, print_function, with_statement
20
21import fcntl
22import os
23
24from . import interface
25
26
27def set_close_exec(fd):
28    flags = fcntl.fcntl(fd, fcntl.F_GETFD)
29    fcntl.fcntl(fd, fcntl.F_SETFD, flags | fcntl.FD_CLOEXEC)
30
31
32def _set_nonblocking(fd):
33    flags = fcntl.fcntl(fd, fcntl.F_GETFL)
34    fcntl.fcntl(fd, fcntl.F_SETFL, flags | os.O_NONBLOCK)
35
36
37class Waker(interface.Waker):
38    def __init__(self):
39        r, w = os.pipe()
40        _set_nonblocking(r)
41        _set_nonblocking(w)
42        set_close_exec(r)
43        set_close_exec(w)
44        self.reader = os.fdopen(r, "rb", 0)
45        self.writer = os.fdopen(w, "wb", 0)
46
47    def fileno(self):
48        return self.reader.fileno()
49
50    def write_fileno(self):
51        return self.writer.fileno()
52
53    def wake(self):
54        try:
55            self.writer.write(b"x")
56        except IOError:
57            pass
58
59    def consume(self):
60        try:
61            while True:
62                result = self.reader.read()
63                if not result:
64                    break
65        except IOError:
66            pass
67
68    def close(self):
69        self.reader.close()
70        self.writer.close()
71