mercurial/selectors2.py
author Gregory Szorc <gregory.szorc@gmail.com>
Wed, 18 Oct 2017 22:57:15 +0200
changeset 34885 df2ff314e36f
parent 34639 a568a46751b6
permissions -rw-r--r--
fsmonitor: warn when fsmonitor could be used fsmonitor can significantly speed up operations on large working directories. But fsmonitor isn't enabled by default, so naive users may not realize there is a potential to make Mercurial faster. This commit introduces a warning to working directory updates when fsmonitor could be used. The following conditions must be met: * Working directory is previously empty * New working directory adds >= N files (currently 50,000) * Running on Linux or MacOS * fsmonitor not enabled * Warning not disabled via config override Because of the empty working directory restriction, most users will only see this warning during `hg clone` (assuming very few users actually do an `hg up null`). The addition of a warning may be considered a BC change. However, clone has printed warnings before. Until recently, Mercurial printed a warning with the server's certificate fingerprint when it wasn't explicitly trusted for example. The warning goes to stderr. So it shouldn't interfere with scripts parsing meaningful output. The OS restriction was on the advice of Facebook engineers, who only feel confident with watchman's stability on the supported platforms. .. feature:: Print warning when fsmonitor isn't being used on a large repository Differential Revision: https://phab.mercurial-scm.org/D894
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
33502
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
     1
""" Back-ported, durable, and portable selectors """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
     2
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
     3
# MIT License
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
     4
#
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
     5
# Copyright (c) 2017 Seth Michael Larson
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
     6
#
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
     7
# Permission is hereby granted, free of charge, to any person obtaining a copy
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
     8
# of this software and associated documentation files (the "Software"), to deal
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
     9
# in the Software without restriction, including without limitation the rights
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    10
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    11
# copies of the Software, and to permit persons to whom the Software is
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    12
# furnished to do so, subject to the following conditions:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    13
#
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    14
# The above copyright notice and this permission notice shall be included in all
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    15
# copies or substantial portions of the Software.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    16
#
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    17
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    18
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    19
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    20
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    21
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    22
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    23
# SOFTWARE.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    24
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    25
# no-check-code
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    26
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    27
from __future__ import absolute_import
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    28
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    29
import collections
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    30
import errno
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    31
import math
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    32
import select
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    33
import socket
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    34
import sys
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    35
import time
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    36
34639
a568a46751b6 selectors2: do not use platform.system()
Jun Wu <quark@fb.com>
parents: 33502
diff changeset
    37
from . import pycompat
a568a46751b6 selectors2: do not use platform.system()
Jun Wu <quark@fb.com>
parents: 33502
diff changeset
    38
33502
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    39
namedtuple = collections.namedtuple
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    40
Mapping = collections.Mapping
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    41
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    42
try:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    43
    monotonic = time.monotonic
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    44
except AttributeError:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    45
    monotonic = time.time
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    46
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    47
__author__ = 'Seth Michael Larson'
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    48
__email__ = 'sethmichaellarson@protonmail.com'
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    49
__version__ = '2.0.0'
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    50
__license__ = 'MIT'
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    51
__url__ = 'https://www.github.com/SethMichaelLarson/selectors2'
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    52
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    53
__all__ = ['EVENT_READ',
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    54
           'EVENT_WRITE',
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    55
           'SelectorKey',
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    56
           'DefaultSelector',
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    57
           'BaseSelector']
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    58
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    59
EVENT_READ = (1 << 0)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    60
EVENT_WRITE = (1 << 1)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    61
_DEFAULT_SELECTOR = None
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    62
_SYSCALL_SENTINEL = object()  # Sentinel in case a system call returns None.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    63
_ERROR_TYPES = (OSError, IOError, socket.error)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    64
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    65
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    66
SelectorKey = namedtuple('SelectorKey', ['fileobj', 'fd', 'events', 'data'])
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    67
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    68
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    69
class _SelectorMapping(Mapping):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    70
    """ Mapping of file objects to selector keys """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    71
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    72
    def __init__(self, selector):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    73
        self._selector = selector
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    74
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    75
    def __len__(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    76
        return len(self._selector._fd_to_key)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    77
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    78
    def __getitem__(self, fileobj):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    79
        try:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    80
            fd = self._selector._fileobj_lookup(fileobj)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    81
            return self._selector._fd_to_key[fd]
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    82
        except KeyError:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    83
            raise KeyError("{0!r} is not registered.".format(fileobj))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    84
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    85
    def __iter__(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    86
        return iter(self._selector._fd_to_key)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    87
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    88
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    89
def _fileobj_to_fd(fileobj):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    90
    """ Return a file descriptor from a file object. If
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    91
    given an integer will simply return that integer back. """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    92
    if isinstance(fileobj, int):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    93
        fd = fileobj
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    94
    else:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    95
        try:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    96
            fd = int(fileobj.fileno())
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    97
        except (AttributeError, TypeError, ValueError):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    98
            raise ValueError("Invalid file object: {0!r}".format(fileobj))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    99
    if fd < 0:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   100
        raise ValueError("Invalid file descriptor: {0}".format(fd))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   101
    return fd
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   102
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   103
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   104
class BaseSelector(object):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   105
    """ Abstract Selector class
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   106
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   107
    A selector supports registering file objects to be monitored
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   108
    for specific I/O events.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   109
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   110
    A file object is a file descriptor or any object with a
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   111
    `fileno()` method. An arbitrary object can be attached to the
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   112
    file object which can be used for example to store context info,
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   113
    a callback, etc.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   114
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   115
    A selector can use various implementations (select(), poll(), epoll(),
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   116
    and kqueue()) depending on the platform. The 'DefaultSelector' class uses
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   117
    the most efficient implementation for the current platform.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   118
    """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   119
    def __init__(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   120
        # Maps file descriptors to keys.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   121
        self._fd_to_key = {}
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   122
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   123
        # Read-only mapping returned by get_map()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   124
        self._map = _SelectorMapping(self)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   125
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   126
    def _fileobj_lookup(self, fileobj):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   127
        """ Return a file descriptor from a file object.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   128
        This wraps _fileobj_to_fd() to do an exhaustive
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   129
        search in case the object is invalid but we still
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   130
        have it in our map. Used by unregister() so we can
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   131
        unregister an object that was previously registered
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   132
        even if it is closed. It is also used by _SelectorMapping
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   133
        """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   134
        try:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   135
            return _fileobj_to_fd(fileobj)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   136
        except ValueError:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   137
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   138
            # Search through all our mapped keys.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   139
            for key in self._fd_to_key.values():
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   140
                if key.fileobj is fileobj:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   141
                    return key.fd
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   142
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   143
            # Raise ValueError after all.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   144
            raise
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   145
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   146
    def register(self, fileobj, events, data=None):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   147
        """ Register a file object for a set of events to monitor. """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   148
        if (not events) or (events & ~(EVENT_READ | EVENT_WRITE)):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   149
            raise ValueError("Invalid events: {0!r}".format(events))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   150
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   151
        key = SelectorKey(fileobj, self._fileobj_lookup(fileobj), events, data)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   152
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   153
        if key.fd in self._fd_to_key:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   154
            raise KeyError("{0!r} (FD {1}) is already registered"
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   155
                           .format(fileobj, key.fd))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   156
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   157
        self._fd_to_key[key.fd] = key
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   158
        return key
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   159
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   160
    def unregister(self, fileobj):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   161
        """ Unregister a file object from being monitored. """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   162
        try:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   163
            key = self._fd_to_key.pop(self._fileobj_lookup(fileobj))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   164
        except KeyError:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   165
            raise KeyError("{0!r} is not registered".format(fileobj))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   166
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   167
        # Getting the fileno of a closed socket on Windows errors with EBADF.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   168
        except socket.error as err:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   169
            if err.errno != errno.EBADF:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   170
                raise
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   171
            else:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   172
                for key in self._fd_to_key.values():
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   173
                    if key.fileobj is fileobj:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   174
                        self._fd_to_key.pop(key.fd)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   175
                        break
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   176
                else:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   177
                    raise KeyError("{0!r} is not registered".format(fileobj))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   178
        return key
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   179
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   180
    def modify(self, fileobj, events, data=None):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   181
        """ Change a registered file object monitored events and data. """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   182
        # NOTE: Some subclasses optimize this operation even further.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   183
        try:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   184
            key = self._fd_to_key[self._fileobj_lookup(fileobj)]
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   185
        except KeyError:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   186
            raise KeyError("{0!r} is not registered".format(fileobj))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   187
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   188
        if events != key.events:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   189
            self.unregister(fileobj)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   190
            key = self.register(fileobj, events, data)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   191
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   192
        elif data != key.data:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   193
            # Use a shortcut to update the data.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   194
            key = key._replace(data=data)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   195
            self._fd_to_key[key.fd] = key
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   196
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   197
        return key
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   198
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   199
    def select(self, timeout=None):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   200
        """ Perform the actual selection until some monitored file objects
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   201
        are ready or the timeout expires. """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   202
        raise NotImplementedError()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   203
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   204
    def close(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   205
        """ Close the selector. This must be called to ensure that all
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   206
        underlying resources are freed. """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   207
        self._fd_to_key.clear()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   208
        self._map = None
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   209
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   210
    def get_key(self, fileobj):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   211
        """ Return the key associated with a registered file object. """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   212
        mapping = self.get_map()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   213
        if mapping is None:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   214
            raise RuntimeError("Selector is closed")
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   215
        try:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   216
            return mapping[fileobj]
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   217
        except KeyError:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   218
            raise KeyError("{0!r} is not registered".format(fileobj))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   219
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   220
    def get_map(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   221
        """ Return a mapping of file objects to selector keys """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   222
        return self._map
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   223
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   224
    def _key_from_fd(self, fd):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   225
        """ Return the key associated to a given file descriptor
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   226
         Return None if it is not found. """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   227
        try:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   228
            return self._fd_to_key[fd]
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   229
        except KeyError:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   230
            return None
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   231
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   232
    def __enter__(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   233
        return self
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   234
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   235
    def __exit__(self, *_):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   236
        self.close()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   237
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   238
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   239
# Almost all platforms have select.select()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   240
if hasattr(select, "select"):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   241
    class SelectSelector(BaseSelector):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   242
        """ Select-based selector. """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   243
        def __init__(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   244
            super(SelectSelector, self).__init__()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   245
            self._readers = set()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   246
            self._writers = set()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   247
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   248
        def register(self, fileobj, events, data=None):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   249
            key = super(SelectSelector, self).register(fileobj, events, data)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   250
            if events & EVENT_READ:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   251
                self._readers.add(key.fd)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   252
            if events & EVENT_WRITE:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   253
                self._writers.add(key.fd)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   254
            return key
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   255
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   256
        def unregister(self, fileobj):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   257
            key = super(SelectSelector, self).unregister(fileobj)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   258
            self._readers.discard(key.fd)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   259
            self._writers.discard(key.fd)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   260
            return key
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   261
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   262
        def select(self, timeout=None):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   263
            # Selecting on empty lists on Windows errors out.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   264
            if not len(self._readers) and not len(self._writers):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   265
                return []
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   266
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   267
            timeout = None if timeout is None else max(timeout, 0.0)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   268
            ready = []
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   269
            r, w, _ = _syscall_wrapper(self._wrap_select, True, self._readers,
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   270
                                       self._writers, timeout)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   271
            r = set(r)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   272
            w = set(w)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   273
            for fd in r | w:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   274
                events = 0
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   275
                if fd in r:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   276
                    events |= EVENT_READ
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   277
                if fd in w:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   278
                    events |= EVENT_WRITE
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   279
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   280
                key = self._key_from_fd(fd)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   281
                if key:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   282
                    ready.append((key, events & key.events))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   283
            return ready
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   284
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   285
        def _wrap_select(self, r, w, timeout=None):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   286
            """ Wrapper for select.select because timeout is a positional arg """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   287
            return select.select(r, w, [], timeout)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   288
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   289
    __all__.append('SelectSelector')
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   290
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   291
    # Jython has a different implementation of .fileno() for socket objects.
34639
a568a46751b6 selectors2: do not use platform.system()
Jun Wu <quark@fb.com>
parents: 33502
diff changeset
   292
    if pycompat.isjython:
33502
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   293
        class _JythonSelectorMapping(object):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   294
            """ This is an implementation of _SelectorMapping that is built
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   295
            for use specifically with Jython, which does not provide a hashable
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   296
            value from socket.socket.fileno(). """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   297
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   298
            def __init__(self, selector):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   299
                assert isinstance(selector, JythonSelectSelector)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   300
                self._selector = selector
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   301
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   302
            def __len__(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   303
                return len(self._selector._sockets)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   304
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   305
            def __getitem__(self, fileobj):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   306
                for sock, key in self._selector._sockets:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   307
                    if sock is fileobj:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   308
                        return key
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   309
                else:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   310
                    raise KeyError("{0!r} is not registered.".format(fileobj))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   311
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   312
        class JythonSelectSelector(SelectSelector):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   313
            """ This is an implementation of SelectSelector that is for Jython
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   314
            which works around that Jython's socket.socket.fileno() does not
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   315
            return an integer fd value. All SelectorKey.fd will be equal to -1
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   316
            and should not be used. This instead uses object id to compare fileobj
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   317
            and will only use select.select as it's the only selector that allows
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   318
            directly passing in socket objects rather than registering fds.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   319
            See: http://bugs.jython.org/issue1678
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   320
                 https://wiki.python.org/jython/NewSocketModule#socket.fileno.28.29_does_not_return_an_integer
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   321
            """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   322
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   323
            def __init__(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   324
                super(JythonSelectSelector, self).__init__()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   325
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   326
                self._sockets = []  # Uses a list of tuples instead of dictionary.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   327
                self._map = _JythonSelectorMapping(self)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   328
                self._readers = []
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   329
                self._writers = []
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   330
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   331
                # Jython has a select.cpython_compatible_select function in older versions.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   332
                self._select_func = getattr(select, 'cpython_compatible_select', select.select)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   333
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   334
            def register(self, fileobj, events, data=None):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   335
                for sock, _ in self._sockets:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   336
                    if sock is fileobj:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   337
                        raise KeyError("{0!r} is already registered"
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   338
                                       .format(fileobj, sock))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   339
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   340
                key = SelectorKey(fileobj, -1, events, data)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   341
                self._sockets.append((fileobj, key))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   342
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   343
                if events & EVENT_READ:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   344
                    self._readers.append(fileobj)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   345
                if events & EVENT_WRITE:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   346
                    self._writers.append(fileobj)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   347
                return key
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   348
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   349
            def unregister(self, fileobj):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   350
                for i, (sock, key) in enumerate(self._sockets):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   351
                    if sock is fileobj:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   352
                        break
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   353
                else:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   354
                    raise KeyError("{0!r} is not registered.".format(fileobj))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   355
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   356
                if key.events & EVENT_READ:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   357
                    self._readers.remove(fileobj)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   358
                if key.events & EVENT_WRITE:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   359
                    self._writers.remove(fileobj)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   360
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   361
                del self._sockets[i]
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   362
                return key
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   363
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   364
            def _wrap_select(self, r, w, timeout=None):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   365
                """ Wrapper for select.select because timeout is a positional arg """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   366
                return self._select_func(r, w, [], timeout)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   367
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   368
        __all__.append('JythonSelectSelector')
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   369
        SelectSelector = JythonSelectSelector  # Override so the wrong selector isn't used.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   370
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   371
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   372
if hasattr(select, "poll"):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   373
    class PollSelector(BaseSelector):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   374
        """ Poll-based selector """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   375
        def __init__(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   376
            super(PollSelector, self).__init__()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   377
            self._poll = select.poll()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   378
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   379
        def register(self, fileobj, events, data=None):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   380
            key = super(PollSelector, self).register(fileobj, events, data)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   381
            event_mask = 0
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   382
            if events & EVENT_READ:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   383
                event_mask |= select.POLLIN
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   384
            if events & EVENT_WRITE:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   385
                event_mask |= select.POLLOUT
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   386
            self._poll.register(key.fd, event_mask)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   387
            return key
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   388
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   389
        def unregister(self, fileobj):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   390
            key = super(PollSelector, self).unregister(fileobj)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   391
            self._poll.unregister(key.fd)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   392
            return key
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   393
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   394
        def _wrap_poll(self, timeout=None):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   395
            """ Wrapper function for select.poll.poll() so that
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   396
            _syscall_wrapper can work with only seconds. """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   397
            if timeout is not None:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   398
                if timeout <= 0:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   399
                    timeout = 0
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   400
                else:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   401
                    # select.poll.poll() has a resolution of 1 millisecond,
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   402
                    # round away from zero to wait *at least* timeout seconds.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   403
                    timeout = math.ceil(timeout * 1000)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   404
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   405
            result = self._poll.poll(timeout)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   406
            return result
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   407
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   408
        def select(self, timeout=None):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   409
            ready = []
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   410
            fd_events = _syscall_wrapper(self._wrap_poll, True, timeout=timeout)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   411
            for fd, event_mask in fd_events:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   412
                events = 0
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   413
                if event_mask & ~select.POLLIN:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   414
                    events |= EVENT_WRITE
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   415
                if event_mask & ~select.POLLOUT:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   416
                    events |= EVENT_READ
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   417
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   418
                key = self._key_from_fd(fd)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   419
                if key:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   420
                    ready.append((key, events & key.events))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   421
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   422
            return ready
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   423
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   424
    __all__.append('PollSelector')
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   425
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   426
if hasattr(select, "epoll"):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   427
    class EpollSelector(BaseSelector):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   428
        """ Epoll-based selector """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   429
        def __init__(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   430
            super(EpollSelector, self).__init__()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   431
            self._epoll = select.epoll()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   432
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   433
        def fileno(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   434
            return self._epoll.fileno()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   435
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   436
        def register(self, fileobj, events, data=None):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   437
            key = super(EpollSelector, self).register(fileobj, events, data)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   438
            events_mask = 0
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   439
            if events & EVENT_READ:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   440
                events_mask |= select.EPOLLIN
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   441
            if events & EVENT_WRITE:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   442
                events_mask |= select.EPOLLOUT
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   443
            _syscall_wrapper(self._epoll.register, False, key.fd, events_mask)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   444
            return key
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   445
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   446
        def unregister(self, fileobj):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   447
            key = super(EpollSelector, self).unregister(fileobj)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   448
            try:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   449
                _syscall_wrapper(self._epoll.unregister, False, key.fd)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   450
            except _ERROR_TYPES:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   451
                # This can occur when the fd was closed since registry.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   452
                pass
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   453
            return key
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   454
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   455
        def select(self, timeout=None):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   456
            if timeout is not None:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   457
                if timeout <= 0:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   458
                    timeout = 0.0
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   459
                else:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   460
                    # select.epoll.poll() has a resolution of 1 millisecond
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   461
                    # but luckily takes seconds so we don't need a wrapper
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   462
                    # like PollSelector. Just for better rounding.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   463
                    timeout = math.ceil(timeout * 1000) * 0.001
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   464
                timeout = float(timeout)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   465
            else:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   466
                timeout = -1.0  # epoll.poll() must have a float.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   467
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   468
            # We always want at least 1 to ensure that select can be called
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   469
            # with no file descriptors registered. Otherwise will fail.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   470
            max_events = max(len(self._fd_to_key), 1)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   471
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   472
            ready = []
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   473
            fd_events = _syscall_wrapper(self._epoll.poll, True,
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   474
                                         timeout=timeout,
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   475
                                         maxevents=max_events)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   476
            for fd, event_mask in fd_events:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   477
                events = 0
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   478
                if event_mask & ~select.EPOLLIN:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   479
                    events |= EVENT_WRITE
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   480
                if event_mask & ~select.EPOLLOUT:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   481
                    events |= EVENT_READ
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   482
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   483
                key = self._key_from_fd(fd)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   484
                if key:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   485
                    ready.append((key, events & key.events))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   486
            return ready
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   487
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   488
        def close(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   489
            self._epoll.close()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   490
            super(EpollSelector, self).close()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   491
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   492
    __all__.append('EpollSelector')
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   493
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   494
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   495
if hasattr(select, "devpoll"):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   496
    class DevpollSelector(BaseSelector):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   497
        """Solaris /dev/poll selector."""
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   498
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   499
        def __init__(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   500
            super(DevpollSelector, self).__init__()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   501
            self._devpoll = select.devpoll()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   502
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   503
        def fileno(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   504
            return self._devpoll.fileno()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   505
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   506
        def register(self, fileobj, events, data=None):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   507
            key = super(DevpollSelector, self).register(fileobj, events, data)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   508
            poll_events = 0
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   509
            if events & EVENT_READ:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   510
                poll_events |= select.POLLIN
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   511
            if events & EVENT_WRITE:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   512
                poll_events |= select.POLLOUT
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   513
            self._devpoll.register(key.fd, poll_events)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   514
            return key
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   515
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   516
        def unregister(self, fileobj):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   517
            key = super(DevpollSelector, self).unregister(fileobj)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   518
            self._devpoll.unregister(key.fd)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   519
            return key
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   520
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   521
        def _wrap_poll(self, timeout=None):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   522
            """ Wrapper function for select.poll.poll() so that
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   523
            _syscall_wrapper can work with only seconds. """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   524
            if timeout is not None:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   525
                if timeout <= 0:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   526
                    timeout = 0
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   527
                else:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   528
                    # select.devpoll.poll() has a resolution of 1 millisecond,
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   529
                    # round away from zero to wait *at least* timeout seconds.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   530
                    timeout = math.ceil(timeout * 1000)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   531
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   532
            result = self._devpoll.poll(timeout)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   533
            return result
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   534
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   535
        def select(self, timeout=None):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   536
            ready = []
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   537
            fd_events = _syscall_wrapper(self._wrap_poll, True, timeout=timeout)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   538
            for fd, event_mask in fd_events:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   539
                events = 0
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   540
                if event_mask & ~select.POLLIN:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   541
                    events |= EVENT_WRITE
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   542
                if event_mask & ~select.POLLOUT:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   543
                    events |= EVENT_READ
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   544
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   545
                key = self._key_from_fd(fd)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   546
                if key:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   547
                    ready.append((key, events & key.events))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   548
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   549
            return ready
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   550
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   551
        def close(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   552
            self._devpoll.close()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   553
            super(DevpollSelector, self).close()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   554
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   555
    __all__.append('DevpollSelector')
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   556
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   557
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   558
if hasattr(select, "kqueue"):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   559
    class KqueueSelector(BaseSelector):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   560
        """ Kqueue / Kevent-based selector """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   561
        def __init__(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   562
            super(KqueueSelector, self).__init__()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   563
            self._kqueue = select.kqueue()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   564
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   565
        def fileno(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   566
            return self._kqueue.fileno()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   567
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   568
        def register(self, fileobj, events, data=None):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   569
            key = super(KqueueSelector, self).register(fileobj, events, data)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   570
            if events & EVENT_READ:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   571
                kevent = select.kevent(key.fd,
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   572
                                       select.KQ_FILTER_READ,
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   573
                                       select.KQ_EV_ADD)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   574
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   575
                _syscall_wrapper(self._kqueue.control, False, [kevent], 0, 0)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   576
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   577
            if events & EVENT_WRITE:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   578
                kevent = select.kevent(key.fd,
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   579
                                       select.KQ_FILTER_WRITE,
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   580
                                       select.KQ_EV_ADD)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   581
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   582
                _syscall_wrapper(self._kqueue.control, False, [kevent], 0, 0)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   583
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   584
            return key
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   585
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   586
        def unregister(self, fileobj):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   587
            key = super(KqueueSelector, self).unregister(fileobj)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   588
            if key.events & EVENT_READ:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   589
                kevent = select.kevent(key.fd,
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   590
                                       select.KQ_FILTER_READ,
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   591
                                       select.KQ_EV_DELETE)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   592
                try:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   593
                    _syscall_wrapper(self._kqueue.control, False, [kevent], 0, 0)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   594
                except _ERROR_TYPES:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   595
                    pass
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   596
            if key.events & EVENT_WRITE:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   597
                kevent = select.kevent(key.fd,
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   598
                                       select.KQ_FILTER_WRITE,
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   599
                                       select.KQ_EV_DELETE)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   600
                try:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   601
                    _syscall_wrapper(self._kqueue.control, False, [kevent], 0, 0)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   602
                except _ERROR_TYPES:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   603
                    pass
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   604
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   605
            return key
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   606
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   607
        def select(self, timeout=None):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   608
            if timeout is not None:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   609
                timeout = max(timeout, 0)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   610
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   611
            max_events = len(self._fd_to_key) * 2
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   612
            ready_fds = {}
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   613
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   614
            kevent_list = _syscall_wrapper(self._kqueue.control, True,
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   615
                                           None, max_events, timeout)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   616
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   617
            for kevent in kevent_list:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   618
                fd = kevent.ident
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   619
                event_mask = kevent.filter
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   620
                events = 0
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   621
                if event_mask == select.KQ_FILTER_READ:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   622
                    events |= EVENT_READ
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   623
                if event_mask == select.KQ_FILTER_WRITE:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   624
                    events |= EVENT_WRITE
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   625
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   626
                key = self._key_from_fd(fd)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   627
                if key:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   628
                    if key.fd not in ready_fds:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   629
                        ready_fds[key.fd] = (key, events & key.events)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   630
                    else:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   631
                        old_events = ready_fds[key.fd][1]
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   632
                        ready_fds[key.fd] = (key, (events | old_events) & key.events)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   633
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   634
            return list(ready_fds.values())
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   635
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   636
        def close(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   637
            self._kqueue.close()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   638
            super(KqueueSelector, self).close()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   639
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   640
    __all__.append('KqueueSelector')
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   641
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   642
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   643
def _can_allocate(struct):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   644
    """ Checks that select structs can be allocated by the underlying
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   645
    operating system, not just advertised by the select module. We don't
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   646
    check select() because we'll be hopeful that most platforms that
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   647
    don't have it available will not advertise it. (ie: GAE) """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   648
    try:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   649
        # select.poll() objects won't fail until used.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   650
        if struct == 'poll':
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   651
            p = select.poll()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   652
            p.poll(0)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   653
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   654
        # All others will fail on allocation.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   655
        else:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   656
            getattr(select, struct)().close()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   657
        return True
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   658
    except (OSError, AttributeError):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   659
        return False
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   660
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   661
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   662
# Python 3.5 uses a more direct route to wrap system calls to increase speed.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   663
if sys.version_info >= (3, 5):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   664
    def _syscall_wrapper(func, _, *args, **kwargs):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   665
        """ This is the short-circuit version of the below logic
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   666
        because in Python 3.5+ all selectors restart system calls. """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   667
        return func(*args, **kwargs)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   668
else:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   669
    def _syscall_wrapper(func, recalc_timeout, *args, **kwargs):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   670
        """ Wrapper function for syscalls that could fail due to EINTR.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   671
        All functions should be retried if there is time left in the timeout
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   672
        in accordance with PEP 475. """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   673
        timeout = kwargs.get("timeout", None)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   674
        if timeout is None:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   675
            expires = None
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   676
            recalc_timeout = False
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   677
        else:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   678
            timeout = float(timeout)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   679
            if timeout < 0.0:  # Timeout less than 0 treated as no timeout.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   680
                expires = None
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   681
            else:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   682
                expires = monotonic() + timeout
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   683
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   684
        args = list(args)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   685
        if recalc_timeout and "timeout" not in kwargs:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   686
            raise ValueError(
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   687
                "Timeout must be in args or kwargs to be recalculated")
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   688
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   689
        result = _SYSCALL_SENTINEL
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   690
        while result is _SYSCALL_SENTINEL:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   691
            try:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   692
                result = func(*args, **kwargs)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   693
            # OSError is thrown by select.select
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   694
            # IOError is thrown by select.epoll.poll
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   695
            # select.error is thrown by select.poll.poll
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   696
            # Aren't we thankful for Python 3.x rework for exceptions?
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   697
            except (OSError, IOError, select.error) as e:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   698
                # select.error wasn't a subclass of OSError in the past.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   699
                errcode = None
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   700
                if hasattr(e, "errno"):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   701
                    errcode = e.errno
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   702
                elif hasattr(e, "args"):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   703
                    errcode = e.args[0]
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   704
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   705
                # Also test for the Windows equivalent of EINTR.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   706
                is_interrupt = (errcode == errno.EINTR or (hasattr(errno, "WSAEINTR") and
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   707
                                                           errcode == errno.WSAEINTR))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   708
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   709
                if is_interrupt:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   710
                    if expires is not None:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   711
                        current_time = monotonic()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   712
                        if current_time > expires:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   713
                            raise OSError(errno=errno.ETIMEDOUT)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   714
                        if recalc_timeout:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   715
                            if "timeout" in kwargs:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   716
                                kwargs["timeout"] = expires - current_time
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   717
                    continue
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   718
                raise
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   719
        return result
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   720
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   721
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   722
# Choose the best implementation, roughly:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   723
# kqueue == devpoll == epoll > poll > select
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   724
# select() also can't accept a FD > FD_SETSIZE (usually around 1024)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   725
def DefaultSelector():
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   726
    """ This function serves as a first call for DefaultSelector to
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   727
    detect if the select module is being monkey-patched incorrectly
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   728
    by eventlet, greenlet, and preserve proper behavior. """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   729
    global _DEFAULT_SELECTOR
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   730
    if _DEFAULT_SELECTOR is None:
34639
a568a46751b6 selectors2: do not use platform.system()
Jun Wu <quark@fb.com>
parents: 33502
diff changeset
   731
        if pycompat.isjython:
33502
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   732
            _DEFAULT_SELECTOR = JythonSelectSelector
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   733
        elif _can_allocate('kqueue'):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   734
            _DEFAULT_SELECTOR = KqueueSelector
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   735
        elif _can_allocate('devpoll'):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   736
            _DEFAULT_SELECTOR = DevpollSelector
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   737
        elif _can_allocate('epoll'):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   738
            _DEFAULT_SELECTOR = EpollSelector
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   739
        elif _can_allocate('poll'):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   740
            _DEFAULT_SELECTOR = PollSelector
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   741
        elif hasattr(select, 'select'):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   742
            _DEFAULT_SELECTOR = SelectSelector
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   743
        else:  # Platform-specific: AppEngine
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   744
            raise RuntimeError('Platform does not have a selector.')
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   745
    return _DEFAULT_SELECTOR()