Exemplo n.º 1
0
    def _poll(self):
        if self._current_iocp:
            if not self._tasks or self._queue:
                if self._timers:
                    ms = max(10, (self._timers[0][0] - self.time()) * 1000)
                else:
                    ms = 10  # Need a 100ms minimum timeout probably, this can be changed
            else:
                ms = 10
            while True:
                status = _overlapped.GetQueuedCompletionStatus(
                    self._port, ms)  # See if anything is ready (LIFO)
                if status is None:  # While we have things to process, keep going
                    break
                ms = 0

                err, transferred, key, address = status

                try:
                    future = self._current_iocp.pop(address)
                    future.set_result(transferred)
                except KeyError:
                    if key not in (0, _overlapped.INVALID_HANDLE_VALUE):
                        CloseHandle(
                            key
                        )  # If we get a handle that doesn't exist or got deleted: Close it
                    continue
        else:
            if self._timers:
                self.sleep(max(0, self._timers[0][0] - self.time()))
Exemplo n.º 2
0
    def _poll(self, timeout=None):
        if timeout is None:
            ms = INFINITE
        elif timeout < 0:
            raise ValueError("negative timeout")
        else:
            # GetQueuedCompletionStatus() has a resolution of 1 millisecond,
            # round away from zero to wait *at least* timeout seconds.
            ms = math.ceil(timeout * 1e3)
            if ms >= INFINITE:
                raise ValueError("timeout too big")

        while True:
            status = _overlapped.GetQueuedCompletionStatus(self._iocp, ms)
            if status is None:
                break
            ms = 0

            err, transferred, key, address = status
            try:
                f, ov, obj, callback = self._cache.pop(address)
            except KeyError:
                if self._loop.get_debug():
                    self._loop.call_exception_handler({
                        'message': ('GetQueuedCompletionStatus() returned an '
                                    'unexpected event'),
                        'status':
                        ('err=%s transferred=%s key=%#x address=%#x' %
                         (err, transferred, key, address)),
                    })

                # key is either zero, or it is used to return a pipe
                # handle which should be closed to avoid a leak.
                if key not in (0, _overlapped.INVALID_HANDLE_VALUE):
                    _winapi.CloseHandle(key)
                continue

            if obj in self._stopped_serving:
                f.cancel()
            # Don't call the callback if _register() already read the result or
            # if the overlapped has been cancelled
            elif not f.done():
                try:
                    value = callback(transferred, key, ov)
                except OSError as e:
                    f.set_exception(e)
                    self._results.append(f)
                else:
                    f.set_result(value)
                    self._results.append(f)

        # Remove unregistered futures
        for ov in self._unregistered:
            self._cache.pop(ov.address, None)
        self._unregistered.clear()
Exemplo n.º 3
0
    def _poll(self, timeout=None):
        """Override in order to handle events in a threadsafe manner."""
        if timeout is None:
            ms = UINT32_MAX  # wait for eternity
        elif timeout < 0:
            raise ValueError("negative timeout")
        else:
            # GetQueuedCompletionStatus() has a resolution of 1 millisecond,
            # round away from zero to wait *at least* timeout seconds.
            ms = math.ceil(timeout * 1e3)
            if ms >= UINT32_MAX:
                raise ValueError("timeout too big")

        with QtCore.QMutexLocker(self._lock):
            while True:
                # self._logger.debug('Polling IOCP with timeout {} ms in thread {}...'.format(
                #     ms, threading.get_ident()))
                status = _overlapped.GetQueuedCompletionStatus(self._iocp, ms)
                if status is None:
                    break

                err, transferred, key, address = status
                try:
                    f, ov, obj, callback = self._cache.pop(address)
                except KeyError:
                    # key is either zero, or it is used to return a pipe
                    # handle which should be closed to avoid a leak.
                    if key not in (0, _overlapped.INVALID_HANDLE_VALUE):
                        _winapi.CloseHandle(key)
                    ms = 0
                    continue

                if obj in self._stopped_serving:
                    f.cancel()
                # Futures might already be resolved or cancelled
                elif not f.done():
                    self.__events.append((f, callback, transferred, key, ov))

                ms = 0