2
2
import contextlib
3
3
import io
4
4
import os
5
- import select
5
+ import sys
6
6
import time
7
7
import unittest
8
8
from concurrent .futures .interpreter import (
17
17
from .util import BaseTestCase , InterpreterPoolMixin , setup_module
18
18
19
19
20
+ WINDOWS = sys .platform .startswith ('win' )
21
+
22
+
23
+ @contextlib .contextmanager
24
+ def nonblocking (fd ):
25
+ blocking = os .get_blocking (fd )
26
+ if blocking :
27
+ os .set_blocking (fd , False )
28
+ try :
29
+ yield
30
+ finally :
31
+ if blocking :
32
+ os .set_blocking (fd , blocking )
33
+
34
+
35
+ def read_file_with_timeout (fd , nbytes , timeout ):
36
+ with nonblocking (fd ):
37
+ end = time .time () + timeout
38
+ try :
39
+ return os .read (fd , nbytes )
40
+ except BlockingIOError :
41
+ pass
42
+ while time .time () < end :
43
+ try :
44
+ return os .read (fd , nbytes )
45
+ except BlockingIOError :
46
+ continue
47
+ else :
48
+ raise TimeoutError ('nothing to read' )
49
+
50
+
51
+ if not WINDOWS :
52
+ import select
53
+ def read_file_with_timeout (fd , nbytes , timeout ):
54
+ r , _ , _ = select .select ([fd ], [], [], timeout )
55
+ if fd not in r :
56
+ raise TimeoutError ('nothing to read' )
57
+ return os .read (fd , nbytes )
58
+
59
+
20
60
def noop ():
21
61
pass
22
62
@@ -27,14 +67,12 @@ def write_msg(fd, msg):
27
67
28
68
29
69
def read_msg (fd , timeout = 10.0 ):
30
- r , _ , _ = select .select ([fd ], [], [], timeout )
31
- if fd not in r :
32
- raise TimeoutError ('nothing to read' )
33
70
msg = b''
34
- while ch := os .read (fd , 1 ):
35
- if ch == b'\0 ' :
36
- return msg
71
+ ch = read_file_with_timeout (fd , 1 , timeout )
72
+ while ch != b'\0 ' :
37
73
msg += ch
74
+ ch = os .read (fd , 1 )
75
+ return msg
38
76
39
77
40
78
def get_current_name ():
0 commit comments