on Windows, select() works only on sockets
    work of anonymous pipes is done as follows:
        PeekNamedPipe returns the amount of data avaialble.
        ReadFile calls with a higher size will be blocked

    so, in order to support size-limited reads, this function doesn't return list of file descriptors,
    but a list of tuples: (fd, bytes_available,)

    since IOLoop.do_iterations calls select with xlist=[], I do not iterate over xlist at all

    since PeekNamedPipe does not have a timeout, we will try run two iterations
    over all the fds in rlist

def select_windows(rlist, wlist, xlist, timeout, retry=True):
    """ on Windows, select() works only on sockets
    work of anonymous pipes is done as follows:
        PeekNamedPipe returns the amount of data avaialble.
        ReadFile calls with a higher size will be blocked

    so, in order to support size-limited reads, this function doesn't return list of file descriptors,
    but a list of tuples: (fd, bytes_available,)

    since IOLoop.do_iterations calls select with xlist=[], I do not iterate over xlist at all

    since PeekNamedPipe does not have a timeout, we will try run two iterations
    over all the fds in rlist
    """
    from ctypes import windll, byref, c_ulong, c_void_p, WinError, GetLastError
    PIPE_ENDED = 109
    read_ready = []
    rlist = [item for item in rlist]
    for i in range(2):
        for fd in rlist:
            bytes_available = c_ulong(0)
            handle = _get_named_pipe_from_fileno(fd.fileno())
            result = windll.kernel32.PeekNamedPipe(c_void_p(handle),        # _In_       HANDLE hNamedPipe,
                                                   None,                    # _Out_opt_  LPVOID lpBuffer,
                                                   c_ulong(0),              # _In_       DWORD nBufferSize,
                                                   None,                    # _Out_opt_  LPDWORD lpBytesRead,
                                                   byref(bytes_available),  # _Out_opt_  LPDWORD lpTotalBytesAvail,
                                                   None)                    # _Out_opt_  LPDWORD lpBytesLeftThisMessage
            if not result:
                last_error = GetLastError()
                if last_error != PIPE_ENDED:
                    raise WinError(last_error)
                continue
            if bytes_available.value:
                read_ready.append((fd, bytes_available.value, ))
                rlist.remove(fd)
        sleep(timeout)
    return read_ready, wlist, xlist