mercurial/thirdparty/selectors2.py
author Joerg Sonnenberger <joerg@bec.de>
Fri, 30 Apr 2021 02:11:58 +0200
changeset 47043 12450fbea288
parent 40787 d1bda397df73
permissions -rw-r--r--
manifests: push down expected node length into the parser This strictly enforces the node length in the manifest lines according to what the repository expects. One test case moves large hash testing into the non-treemanifest part as treemanifests don't provide an interface for overriding just the node length for now. Differential Revision: https://phab.mercurial-scm.org/D10533
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
from __future__ import absolute_import
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
import collections
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    28
import errno
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    29
import math
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    30
import select
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    31
import socket
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    32
import sys
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    33
import time
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    34
35245
414114a7c18f thirdparty: move selectors2 module to where it should be
Yuya Nishihara <yuya@tcha.org>
parents: 34639
diff changeset
    35
from .. import pycompat
34639
a568a46751b6 selectors2: do not use platform.system()
Jun Wu <quark@fb.com>
parents: 33502
diff changeset
    36
33502
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    37
namedtuple = collections.namedtuple
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    38
Mapping = collections.Mapping
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    39
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    40
try:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    41
    monotonic = time.monotonic
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    42
except AttributeError:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    43
    monotonic = time.time
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    44
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    45
__author__ = 'Seth Michael Larson'
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    46
__email__ = 'sethmichaellarson@protonmail.com'
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    47
__version__ = '2.0.0'
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    48
__license__ = 'MIT'
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    49
__url__ = 'https://www.github.com/SethMichaelLarson/selectors2'
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    50
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    51
__all__ = ['EVENT_READ',
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    52
           'EVENT_WRITE',
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    53
           'SelectorKey',
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    54
           'DefaultSelector',
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    55
           'BaseSelector']
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    56
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    57
EVENT_READ = (1 << 0)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    58
EVENT_WRITE = (1 << 1)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    59
_DEFAULT_SELECTOR = None
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    60
_SYSCALL_SENTINEL = object()  # Sentinel in case a system call returns None.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    61
_ERROR_TYPES = (OSError, IOError, socket.error)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    62
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    63
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    64
SelectorKey = namedtuple('SelectorKey', ['fileobj', 'fd', 'events', 'data'])
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
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    67
class _SelectorMapping(Mapping):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    68
    """ Mapping of file objects to selector keys """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    69
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    70
    def __init__(self, selector):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    71
        self._selector = selector
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    72
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    73
    def __len__(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    74
        return len(self._selector._fd_to_key)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    75
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    76
    def __getitem__(self, fileobj):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    77
        try:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    78
            fd = self._selector._fileobj_lookup(fileobj)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    79
            return self._selector._fd_to_key[fd]
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    80
        except KeyError:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    81
            raise KeyError("{0!r} is not registered.".format(fileobj))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    82
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    83
    def __iter__(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    84
        return iter(self._selector._fd_to_key)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    85
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    86
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    87
def _fileobj_to_fd(fileobj):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    88
    """ Return a file descriptor from a file object. If
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    89
    given an integer will simply return that integer back. """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    90
    if isinstance(fileobj, int):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    91
        fd = fileobj
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    92
    else:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    93
        try:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    94
            fd = int(fileobj.fileno())
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    95
        except (AttributeError, TypeError, ValueError):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    96
            raise ValueError("Invalid file object: {0!r}".format(fileobj))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    97
    if fd < 0:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    98
        raise ValueError("Invalid file descriptor: {0}".format(fd))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
    99
    return fd
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   100
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   101
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   102
class BaseSelector(object):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   103
    """ Abstract Selector class
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   104
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   105
    A selector supports registering file objects to be monitored
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   106
    for specific I/O events.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   107
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   108
    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
   109
    `fileno()` method. An arbitrary object can be attached to the
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   110
    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
   111
    a callback, etc.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   112
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   113
    A selector can use various implementations (select(), poll(), epoll(),
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   114
    and kqueue()) depending on the platform. The 'DefaultSelector' class uses
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   115
    the most efficient implementation for the current platform.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   116
    """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   117
    def __init__(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   118
        # Maps file descriptors to keys.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   119
        self._fd_to_key = {}
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   120
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   121
        # Read-only mapping returned by get_map()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   122
        self._map = _SelectorMapping(self)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   123
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   124
    def _fileobj_lookup(self, fileobj):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   125
        """ Return a file descriptor from a file object.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   126
        This wraps _fileobj_to_fd() to do an exhaustive
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   127
        search in case the object is invalid but we still
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   128
        have it in our map. Used by unregister() so we can
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   129
        unregister an object that was previously registered
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   130
        even if it is closed. It is also used by _SelectorMapping
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   131
        """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   132
        try:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   133
            return _fileobj_to_fd(fileobj)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   134
        except ValueError:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   135
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   136
            # Search through all our mapped keys.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   137
            for key in self._fd_to_key.values():
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   138
                if key.fileobj is fileobj:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   139
                    return key.fd
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   140
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   141
            # Raise ValueError after all.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   142
            raise
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   143
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   144
    def register(self, fileobj, events, data=None):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   145
        """ Register a file object for a set of events to monitor. """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   146
        if (not events) or (events & ~(EVENT_READ | EVENT_WRITE)):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   147
            raise ValueError("Invalid events: {0!r}".format(events))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   148
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   149
        key = SelectorKey(fileobj, self._fileobj_lookup(fileobj), events, data)
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
        if key.fd in self._fd_to_key:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   152
            raise KeyError("{0!r} (FD {1}) is already registered"
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   153
                           .format(fileobj, key.fd))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   154
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   155
        self._fd_to_key[key.fd] = key
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   156
        return key
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   157
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   158
    def unregister(self, fileobj):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   159
        """ Unregister a file object from being monitored. """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   160
        try:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   161
            key = self._fd_to_key.pop(self._fileobj_lookup(fileobj))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   162
        except KeyError:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   163
            raise KeyError("{0!r} is not registered".format(fileobj))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   164
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   165
        # 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
   166
        except socket.error as err:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   167
            if err.errno != errno.EBADF:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   168
                raise
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   169
            else:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   170
                for key in self._fd_to_key.values():
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   171
                    if key.fileobj is fileobj:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   172
                        self._fd_to_key.pop(key.fd)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   173
                        break
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   174
                else:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   175
                    raise KeyError("{0!r} is not registered".format(fileobj))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   176
        return key
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   177
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   178
    def modify(self, fileobj, events, data=None):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   179
        """ Change a registered file object monitored events and data. """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   180
        # NOTE: Some subclasses optimize this operation even further.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   181
        try:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   182
            key = self._fd_to_key[self._fileobj_lookup(fileobj)]
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   183
        except KeyError:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   184
            raise KeyError("{0!r} is not registered".format(fileobj))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   185
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   186
        if events != key.events:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   187
            self.unregister(fileobj)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   188
            key = self.register(fileobj, events, data)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   189
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   190
        elif data != key.data:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   191
            # Use a shortcut to update the data.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   192
            key = key._replace(data=data)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   193
            self._fd_to_key[key.fd] = key
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   194
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   195
        return 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
    def select(self, timeout=None):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   198
        """ Perform the actual selection until some monitored file objects
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   199
        are ready or the timeout expires. """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   200
        raise NotImplementedError()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   201
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   202
    def close(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   203
        """ Close the selector. This must be called to ensure that all
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   204
        underlying resources are freed. """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   205
        self._fd_to_key.clear()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   206
        self._map = None
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   207
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   208
    def get_key(self, fileobj):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   209
        """ Return the key associated with a registered file object. """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   210
        mapping = self.get_map()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   211
        if mapping is None:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   212
            raise RuntimeError("Selector is closed")
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   213
        try:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   214
            return mapping[fileobj]
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   215
        except KeyError:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   216
            raise KeyError("{0!r} is not registered".format(fileobj))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   217
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   218
    def get_map(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   219
        """ Return a mapping of file objects to selector keys """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   220
        return self._map
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   221
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   222
    def _key_from_fd(self, fd):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   223
        """ Return the key associated to a given file descriptor
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   224
         Return None if it is not found. """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   225
        try:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   226
            return self._fd_to_key[fd]
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   227
        except KeyError:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   228
            return None
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   229
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   230
    def __enter__(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   231
        return self
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   232
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   233
    def __exit__(self, *_):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   234
        self.close()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   235
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   236
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   237
# Almost all platforms have select.select()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   238
if hasattr(select, "select"):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   239
    class SelectSelector(BaseSelector):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   240
        """ Select-based selector. """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   241
        def __init__(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   242
            super(SelectSelector, self).__init__()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   243
            self._readers = set()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   244
            self._writers = set()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   245
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   246
        def register(self, fileobj, events, data=None):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   247
            key = super(SelectSelector, self).register(fileobj, events, data)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   248
            if events & EVENT_READ:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   249
                self._readers.add(key.fd)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   250
            if events & EVENT_WRITE:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   251
                self._writers.add(key.fd)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   252
            return key
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   253
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   254
        def unregister(self, fileobj):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   255
            key = super(SelectSelector, self).unregister(fileobj)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   256
            self._readers.discard(key.fd)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   257
            self._writers.discard(key.fd)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   258
            return key
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   259
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   260
        def select(self, timeout=None):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   261
            # Selecting on empty lists on Windows errors out.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   262
            if not len(self._readers) and not len(self._writers):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   263
                return []
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   264
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   265
            timeout = None if timeout is None else max(timeout, 0.0)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   266
            ready = []
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   267
            r, w, _ = _syscall_wrapper(self._wrap_select, True, self._readers,
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   268
                                       self._writers, timeout)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   269
            r = set(r)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   270
            w = set(w)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   271
            for fd in r | w:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   272
                events = 0
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   273
                if fd in r:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   274
                    events |= EVENT_READ
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   275
                if fd in w:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   276
                    events |= EVENT_WRITE
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   277
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   278
                key = self._key_from_fd(fd)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   279
                if key:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   280
                    ready.append((key, events & key.events))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   281
            return ready
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   282
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   283
        def _wrap_select(self, r, w, timeout=None):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   284
            """ Wrapper for select.select because timeout is a positional arg """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   285
            return select.select(r, w, [], timeout)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   286
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   287
    __all__.append('SelectSelector')
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
    # 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
   290
    if pycompat.isjython:
33502
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   291
        class _JythonSelectorMapping(object):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   292
            """ This is an implementation of _SelectorMapping that is built
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   293
            for use specifically with Jython, which does not provide a hashable
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   294
            value from socket.socket.fileno(). """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   295
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   296
            def __init__(self, selector):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   297
                assert isinstance(selector, JythonSelectSelector)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   298
                self._selector = selector
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   299
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   300
            def __len__(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   301
                return len(self._selector._sockets)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   302
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   303
            def __getitem__(self, fileobj):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   304
                for sock, key in self._selector._sockets:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   305
                    if sock is fileobj:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   306
                        return key
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   307
                else:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   308
                    raise KeyError("{0!r} is not registered.".format(fileobj))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   309
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   310
        class JythonSelectSelector(SelectSelector):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   311
            """ This is an implementation of SelectSelector that is for Jython
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   312
            which works around that Jython's socket.socket.fileno() does not
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   313
            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
   314
            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
   315
            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
   316
            directly passing in socket objects rather than registering fds.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   317
            See: http://bugs.jython.org/issue1678
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   318
                 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
   319
            """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   320
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   321
            def __init__(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   322
                super(JythonSelectSelector, self).__init__()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   323
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   324
                self._sockets = []  # Uses a list of tuples instead of dictionary.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   325
                self._map = _JythonSelectorMapping(self)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   326
                self._readers = []
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   327
                self._writers = []
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   328
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   329
                # Jython has a select.cpython_compatible_select function in older versions.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   330
                self._select_func = getattr(select, 'cpython_compatible_select', select.select)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   331
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   332
            def register(self, fileobj, events, data=None):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   333
                for sock, _ in self._sockets:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   334
                    if sock is fileobj:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   335
                        raise KeyError("{0!r} is already registered"
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   336
                                       .format(fileobj, sock))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   337
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   338
                key = SelectorKey(fileobj, -1, events, data)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   339
                self._sockets.append((fileobj, key))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   340
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   341
                if events & EVENT_READ:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   342
                    self._readers.append(fileobj)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   343
                if events & EVENT_WRITE:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   344
                    self._writers.append(fileobj)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   345
                return key
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   346
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   347
            def unregister(self, fileobj):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   348
                for i, (sock, key) in enumerate(self._sockets):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   349
                    if sock is fileobj:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   350
                        break
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   351
                else:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   352
                    raise KeyError("{0!r} is not registered.".format(fileobj))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   353
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   354
                if key.events & EVENT_READ:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   355
                    self._readers.remove(fileobj)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   356
                if key.events & EVENT_WRITE:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   357
                    self._writers.remove(fileobj)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   358
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   359
                del self._sockets[i]
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   360
                return key
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   361
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   362
            def _wrap_select(self, r, w, timeout=None):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   363
                """ Wrapper for select.select because timeout is a positional arg """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   364
                return self._select_func(r, w, [], timeout)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   365
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   366
        __all__.append('JythonSelectSelector')
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   367
        SelectSelector = JythonSelectSelector  # Override so the wrong selector isn't used.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   368
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   369
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   370
if hasattr(select, "poll"):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   371
    class PollSelector(BaseSelector):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   372
        """ Poll-based selector """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   373
        def __init__(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   374
            super(PollSelector, self).__init__()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   375
            self._poll = select.poll()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   376
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   377
        def register(self, fileobj, events, data=None):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   378
            key = super(PollSelector, self).register(fileobj, events, data)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   379
            event_mask = 0
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   380
            if events & EVENT_READ:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   381
                event_mask |= select.POLLIN
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   382
            if events & EVENT_WRITE:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   383
                event_mask |= select.POLLOUT
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   384
            self._poll.register(key.fd, event_mask)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   385
            return key
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   386
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   387
        def unregister(self, fileobj):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   388
            key = super(PollSelector, self).unregister(fileobj)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   389
            self._poll.unregister(key.fd)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   390
            return key
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   391
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   392
        def _wrap_poll(self, timeout=None):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   393
            """ Wrapper function for select.poll.poll() so that
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   394
            _syscall_wrapper can work with only seconds. """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   395
            if timeout is not None:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   396
                if timeout <= 0:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   397
                    timeout = 0
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   398
                else:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   399
                    # select.poll.poll() has a resolution of 1 millisecond,
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   400
                    # round away from zero to wait *at least* timeout seconds.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   401
                    timeout = math.ceil(timeout * 1000)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   402
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   403
            result = self._poll.poll(timeout)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   404
            return result
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   405
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   406
        def select(self, timeout=None):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   407
            ready = []
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   408
            fd_events = _syscall_wrapper(self._wrap_poll, True, timeout=timeout)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   409
            for fd, event_mask in fd_events:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   410
                events = 0
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   411
                if event_mask & ~select.POLLIN:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   412
                    events |= EVENT_WRITE
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   413
                if event_mask & ~select.POLLOUT:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   414
                    events |= EVENT_READ
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   415
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   416
                key = self._key_from_fd(fd)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   417
                if key:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   418
                    ready.append((key, events & key.events))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   419
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   420
            return ready
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
    __all__.append('PollSelector')
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
if hasattr(select, "epoll"):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   425
    class EpollSelector(BaseSelector):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   426
        """ Epoll-based selector """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   427
        def __init__(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   428
            super(EpollSelector, self).__init__()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   429
            self._epoll = select.epoll()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   430
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   431
        def fileno(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   432
            return self._epoll.fileno()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   433
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   434
        def register(self, fileobj, events, data=None):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   435
            key = super(EpollSelector, self).register(fileobj, events, data)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   436
            events_mask = 0
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   437
            if events & EVENT_READ:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   438
                events_mask |= select.EPOLLIN
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   439
            if events & EVENT_WRITE:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   440
                events_mask |= select.EPOLLOUT
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   441
            _syscall_wrapper(self._epoll.register, False, key.fd, events_mask)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   442
            return key
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   443
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   444
        def unregister(self, fileobj):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   445
            key = super(EpollSelector, self).unregister(fileobj)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   446
            try:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   447
                _syscall_wrapper(self._epoll.unregister, False, key.fd)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   448
            except _ERROR_TYPES:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   449
                # This can occur when the fd was closed since registry.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   450
                pass
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   451
            return key
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   452
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   453
        def select(self, timeout=None):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   454
            if timeout is not None:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   455
                if timeout <= 0:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   456
                    timeout = 0.0
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   457
                else:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   458
                    # select.epoll.poll() has a resolution of 1 millisecond
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   459
                    # but luckily takes seconds so we don't need a wrapper
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   460
                    # like PollSelector. Just for better rounding.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   461
                    timeout = math.ceil(timeout * 1000) * 0.001
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   462
                timeout = float(timeout)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   463
            else:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   464
                timeout = -1.0  # epoll.poll() must have a float.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   465
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   466
            # 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
   467
            # with no file descriptors registered. Otherwise will fail.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   468
            max_events = max(len(self._fd_to_key), 1)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   469
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   470
            ready = []
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   471
            fd_events = _syscall_wrapper(self._epoll.poll, True,
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   472
                                         timeout=timeout,
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   473
                                         maxevents=max_events)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   474
            for fd, event_mask in fd_events:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   475
                events = 0
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   476
                if event_mask & ~select.EPOLLIN:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   477
                    events |= EVENT_WRITE
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   478
                if event_mask & ~select.EPOLLOUT:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   479
                    events |= EVENT_READ
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   480
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   481
                key = self._key_from_fd(fd)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   482
                if key:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   483
                    ready.append((key, events & key.events))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   484
            return ready
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   485
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   486
        def close(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   487
            self._epoll.close()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   488
            super(EpollSelector, self).close()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   489
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   490
    __all__.append('EpollSelector')
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
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   493
if hasattr(select, "devpoll"):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   494
    class DevpollSelector(BaseSelector):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   495
        """Solaris /dev/poll selector."""
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   496
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   497
        def __init__(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   498
            super(DevpollSelector, self).__init__()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   499
            self._devpoll = select.devpoll()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   500
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   501
        def fileno(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   502
            return self._devpoll.fileno()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   503
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   504
        def register(self, fileobj, events, data=None):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   505
            key = super(DevpollSelector, self).register(fileobj, events, data)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   506
            poll_events = 0
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   507
            if events & EVENT_READ:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   508
                poll_events |= select.POLLIN
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   509
            if events & EVENT_WRITE:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   510
                poll_events |= select.POLLOUT
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   511
            self._devpoll.register(key.fd, poll_events)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   512
            return key
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   513
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   514
        def unregister(self, fileobj):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   515
            key = super(DevpollSelector, self).unregister(fileobj)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   516
            self._devpoll.unregister(key.fd)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   517
            return key
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   518
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   519
        def _wrap_poll(self, timeout=None):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   520
            """ Wrapper function for select.poll.poll() so that
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   521
            _syscall_wrapper can work with only seconds. """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   522
            if timeout is not None:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   523
                if timeout <= 0:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   524
                    timeout = 0
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   525
                else:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   526
                    # select.devpoll.poll() has a resolution of 1 millisecond,
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   527
                    # round away from zero to wait *at least* timeout seconds.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   528
                    timeout = math.ceil(timeout * 1000)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   529
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   530
            result = self._devpoll.poll(timeout)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   531
            return result
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   532
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   533
        def select(self, timeout=None):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   534
            ready = []
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   535
            fd_events = _syscall_wrapper(self._wrap_poll, True, timeout=timeout)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   536
            for fd, event_mask in fd_events:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   537
                events = 0
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   538
                if event_mask & ~select.POLLIN:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   539
                    events |= EVENT_WRITE
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   540
                if event_mask & ~select.POLLOUT:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   541
                    events |= EVENT_READ
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   542
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   543
                key = self._key_from_fd(fd)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   544
                if key:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   545
                    ready.append((key, events & key.events))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   546
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   547
            return ready
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
        def close(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   550
            self._devpoll.close()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   551
            super(DevpollSelector, self).close()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   552
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   553
    __all__.append('DevpollSelector')
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
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   556
if hasattr(select, "kqueue"):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   557
    class KqueueSelector(BaseSelector):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   558
        """ Kqueue / Kevent-based selector """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   559
        def __init__(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   560
            super(KqueueSelector, self).__init__()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   561
            self._kqueue = select.kqueue()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   562
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   563
        def fileno(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   564
            return self._kqueue.fileno()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   565
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   566
        def register(self, fileobj, events, data=None):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   567
            key = super(KqueueSelector, self).register(fileobj, events, data)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   568
            if events & EVENT_READ:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   569
                kevent = select.kevent(key.fd,
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   570
                                       select.KQ_FILTER_READ,
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   571
                                       select.KQ_EV_ADD)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   572
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   573
                _syscall_wrapper(self._kqueue.control, False, [kevent], 0, 0)
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
            if events & EVENT_WRITE:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   576
                kevent = select.kevent(key.fd,
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   577
                                       select.KQ_FILTER_WRITE,
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   578
                                       select.KQ_EV_ADD)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   579
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   580
                _syscall_wrapper(self._kqueue.control, False, [kevent], 0, 0)
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
            return key
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
        def unregister(self, fileobj):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   585
            key = super(KqueueSelector, self).unregister(fileobj)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   586
            if key.events & EVENT_READ:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   587
                kevent = select.kevent(key.fd,
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   588
                                       select.KQ_FILTER_READ,
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   589
                                       select.KQ_EV_DELETE)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   590
                try:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   591
                    _syscall_wrapper(self._kqueue.control, False, [kevent], 0, 0)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   592
                except _ERROR_TYPES:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   593
                    pass
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   594
            if key.events & EVENT_WRITE:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   595
                kevent = select.kevent(key.fd,
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   596
                                       select.KQ_FILTER_WRITE,
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   597
                                       select.KQ_EV_DELETE)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   598
                try:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   599
                    _syscall_wrapper(self._kqueue.control, False, [kevent], 0, 0)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   600
                except _ERROR_TYPES:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   601
                    pass
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   602
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   603
            return key
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
        def select(self, timeout=None):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   606
            if timeout is not None:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   607
                timeout = max(timeout, 0)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   608
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   609
            max_events = len(self._fd_to_key) * 2
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   610
            ready_fds = {}
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   611
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   612
            kevent_list = _syscall_wrapper(self._kqueue.control, True,
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   613
                                           None, max_events, timeout)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   614
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   615
            for kevent in kevent_list:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   616
                fd = kevent.ident
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   617
                event_mask = kevent.filter
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   618
                events = 0
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   619
                if event_mask == select.KQ_FILTER_READ:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   620
                    events |= EVENT_READ
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   621
                if event_mask == select.KQ_FILTER_WRITE:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   622
                    events |= EVENT_WRITE
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   623
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   624
                key = self._key_from_fd(fd)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   625
                if key:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   626
                    if key.fd not in ready_fds:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   627
                        ready_fds[key.fd] = (key, events & key.events)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   628
                    else:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   629
                        old_events = ready_fds[key.fd][1]
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   630
                        ready_fds[key.fd] = (key, (events | old_events) & key.events)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   631
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   632
            return list(ready_fds.values())
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
        def close(self):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   635
            self._kqueue.close()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   636
            super(KqueueSelector, self).close()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   637
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   638
    __all__.append('KqueueSelector')
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
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   641
def _can_allocate(struct):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   642
    """ Checks that select structs can be allocated by the underlying
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   643
    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
   644
    check select() because we'll be hopeful that most platforms that
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   645
    don't have it available will not advertise it. (ie: GAE) """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   646
    try:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   647
        # select.poll() objects won't fail until used.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   648
        if struct == 'poll':
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   649
            p = select.poll()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   650
            p.poll(0)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   651
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   652
        # All others will fail on allocation.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   653
        else:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   654
            getattr(select, struct)().close()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   655
        return True
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   656
    except (OSError, AttributeError):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   657
        return False
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   658
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   659
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   660
# 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
   661
if sys.version_info >= (3, 5):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   662
    def _syscall_wrapper(func, _, *args, **kwargs):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   663
        """ This is the short-circuit version of the below logic
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   664
        because in Python 3.5+ all selectors restart system calls. """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   665
        return func(*args, **kwargs)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   666
else:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   667
    def _syscall_wrapper(func, recalc_timeout, *args, **kwargs):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   668
        """ Wrapper function for syscalls that could fail due to EINTR.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   669
        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
   670
        in accordance with PEP 475. """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   671
        timeout = kwargs.get("timeout", None)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   672
        if timeout is None:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   673
            expires = None
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   674
            recalc_timeout = False
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   675
        else:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   676
            timeout = float(timeout)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   677
            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
   678
                expires = None
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   679
            else:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   680
                expires = monotonic() + timeout
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   681
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   682
        args = list(args)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   683
        if recalc_timeout and "timeout" not in kwargs:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   684
            raise ValueError(
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   685
                "Timeout must be in args or kwargs to be recalculated")
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   686
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   687
        result = _SYSCALL_SENTINEL
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   688
        while result is _SYSCALL_SENTINEL:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   689
            try:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   690
                result = func(*args, **kwargs)
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   691
            # OSError is thrown by select.select
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   692
            # IOError is thrown by select.epoll.poll
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   693
            # select.error is thrown by select.poll.poll
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   694
            # Aren't we thankful for Python 3.x rework for exceptions?
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   695
            except (OSError, IOError, select.error) as e:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   696
                # select.error wasn't a subclass of OSError in the past.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   697
                errcode = None
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   698
                if hasattr(e, "errno"):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   699
                    errcode = e.errno
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   700
                elif hasattr(e, "args"):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   701
                    errcode = e.args[0]
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   702
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   703
                # Also test for the Windows equivalent of EINTR.
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   704
                is_interrupt = (errcode == errno.EINTR or (hasattr(errno, "WSAEINTR") and
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   705
                                                           errcode == errno.WSAEINTR))
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   706
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   707
                if is_interrupt:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   708
                    if expires is not None:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   709
                        current_time = monotonic()
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   710
                        if current_time > expires:
40787
d1bda397df73 selectors2: backport minimal fix of timeout handling from 2.0.1
Yuya Nishihara <yuya@tcha.org>
parents: 35245
diff changeset
   711
                            raise OSError(errno.ETIMEDOUT, 'Connection timed out')
33502
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   712
                        if recalc_timeout:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   713
                            if "timeout" in kwargs:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   714
                                kwargs["timeout"] = expires - current_time
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   715
                    continue
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   716
                raise
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   717
        return result
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   718
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   719
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   720
# Choose the best implementation, roughly:
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   721
# kqueue == devpoll == epoll > poll > select
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   722
# 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
   723
def DefaultSelector():
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   724
    """ This function serves as a first call for DefaultSelector to
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   725
    detect if the select module is being monkey-patched incorrectly
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   726
    by eventlet, greenlet, and preserve proper behavior. """
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   727
    global _DEFAULT_SELECTOR
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   728
    if _DEFAULT_SELECTOR is None:
34639
a568a46751b6 selectors2: do not use platform.system()
Jun Wu <quark@fb.com>
parents: 33502
diff changeset
   729
        if pycompat.isjython:
33502
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   730
            _DEFAULT_SELECTOR = JythonSelectSelector
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   731
        elif _can_allocate('kqueue'):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   732
            _DEFAULT_SELECTOR = KqueueSelector
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   733
        elif _can_allocate('devpoll'):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   734
            _DEFAULT_SELECTOR = DevpollSelector
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   735
        elif _can_allocate('epoll'):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   736
            _DEFAULT_SELECTOR = EpollSelector
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   737
        elif _can_allocate('poll'):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   738
            _DEFAULT_SELECTOR = PollSelector
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   739
        elif hasattr(select, 'select'):
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   740
            _DEFAULT_SELECTOR = SelectSelector
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   741
        else:  # Platform-specific: AppEngine
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   742
            raise RuntimeError('Platform does not have a selector.')
5d0c0c8d2929 selector2: vendor selector2 library
Jun Wu <quark@fb.com>
parents:
diff changeset
   743
    return _DEFAULT_SELECTOR()