| 1046 | if sys.platform == 'win32': |
| 1047 | |
| 1048 | def _exhaustive_wait(handles, timeout): |
| 1049 | # Return ALL handles which are currently signalled. (Only |
| 1050 | # returning the first signalled might create starvation issues.) |
| 1051 | L = list(handles) |
| 1052 | ready = [] |
| 1053 | # Windows limits WaitForMultipleObjects at 64 handles, and we use a |
| 1054 | # few for synchronisation, so we switch to batched waits at 60. |
| 1055 | if len(L) > 60: |
| 1056 | try: |
| 1057 | res = _winapi.BatchedWaitForMultipleObjects(L, False, timeout) |
| 1058 | except TimeoutError: |
| 1059 | return [] |
| 1060 | ready.extend(L[i] for i in res) |
| 1061 | if res: |
| 1062 | L = [h for i, h in enumerate(L) if i > res[0] & i not in res] |
| 1063 | timeout = 0 |
| 1064 | while L: |
| 1065 | short_L = L[:60] if len(L) > 60 else L |
| 1066 | res = _winapi.WaitForMultipleObjects(short_L, False, timeout) |
| 1067 | if res == WAIT_TIMEOUT: |
| 1068 | break |
| 1069 | elif WAIT_OBJECT_0 <= res < WAIT_OBJECT_0 + len(L): |
| 1070 | res -= WAIT_OBJECT_0 |
| 1071 | elif WAIT_ABANDONED_0 <= res < WAIT_ABANDONED_0 + len(L): |
| 1072 | res -= WAIT_ABANDONED_0 |
| 1073 | else: |
| 1074 | raise RuntimeError('Should not get here') |
| 1075 | ready.append(L[res]) |
| 1076 | L = L[res+1:] |
| 1077 | timeout = 0 |
| 1078 | return ready |
| 1079 | |
| 1080 | _ready_errors = {_winapi.ERROR_BROKEN_PIPE, _winapi.ERROR_NETNAME_DELETED} |
| 1081 | |