| 1008 | if sys.platform == 'win32': |
| 1009 | |
| 1010 | def _exhaustive_wait(handles, timeout): |
| 1011 | # Return ALL handles which are currently signalled. (Only |
| 1012 | # returning the first signalled might create starvation issues.) |
| 1013 | L = list(handles) |
| 1014 | ready = [] |
| 1015 | # Windows limits WaitForMultipleObjects at 64 handles, and we use a |
| 1016 | # few for synchronisation, so we switch to batched waits at 60. |
| 1017 | if len(L) > 60: |
| 1018 | try: |
| 1019 | res = _winapi.BatchedWaitForMultipleObjects(L, False, timeout) |
| 1020 | except TimeoutError: |
| 1021 | return [] |
| 1022 | ready.extend(L[i] for i in res) |
| 1023 | if res: |
| 1024 | L = [h for i, h in enumerate(L) if i > res[0] & i not in res] |
| 1025 | timeout = 0 |
| 1026 | while L: |
| 1027 | short_L = L[:60] if len(L) > 60 else L |
| 1028 | res = _winapi.WaitForMultipleObjects(short_L, False, timeout) |
| 1029 | if res == WAIT_TIMEOUT: |
| 1030 | break |
| 1031 | elif WAIT_OBJECT_0 <= res < WAIT_OBJECT_0 + len(L): |
| 1032 | res -= WAIT_OBJECT_0 |
| 1033 | elif WAIT_ABANDONED_0 <= res < WAIT_ABANDONED_0 + len(L): |
| 1034 | res -= WAIT_ABANDONED_0 |
| 1035 | else: |
| 1036 | raise RuntimeError('Should not get here') |
| 1037 | ready.append(L[res]) |
| 1038 | L = L[res+1:] |
| 1039 | timeout = 0 |
| 1040 | return ready |
| 1041 | |
| 1042 | _ready_errors = {_winapi.ERROR_BROKEN_PIPE, _winapi.ERROR_NETNAME_DELETED} |
| 1043 | |