equal
deleted
inserted
replaced
61 if n >= 1: |
61 if n >= 1: |
62 return n |
62 return n |
63 except ValueError: |
63 except ValueError: |
64 raise error.Abort(_(b'number of cpus must be an integer')) |
64 raise error.Abort(_(b'number of cpus must be an integer')) |
65 return min(max(countcpus(), 4), 32) |
65 return min(max(countcpus(), 4), 32) |
|
66 |
|
67 |
|
68 if pycompat.ispy3: |
|
69 |
|
70 class _blockingreader(object): |
|
71 def __init__(self, wrapped): |
|
72 self._wrapped = wrapped |
|
73 |
|
74 def __getattr__(self, attr): |
|
75 return getattr(self._wrapped, attr) |
|
76 |
|
77 # issue multiple reads until size is fulfilled |
|
78 def read(self, size=-1): |
|
79 if size < 0: |
|
80 return self._wrapped.readall() |
|
81 |
|
82 buf = bytearray(size) |
|
83 view = memoryview(buf) |
|
84 pos = 0 |
|
85 |
|
86 while pos < size: |
|
87 ret = self._wrapped.readinto(view[pos:]) |
|
88 if not ret: |
|
89 break |
|
90 pos += ret |
|
91 |
|
92 del view |
|
93 del buf[pos:] |
|
94 return buf |
|
95 |
|
96 |
|
97 else: |
|
98 |
|
99 def _blockingreader(wrapped): |
|
100 return wrapped |
66 |
101 |
67 |
102 |
68 if pycompat.isposix or pycompat.iswindows: |
103 if pycompat.isposix or pycompat.iswindows: |
69 _STARTUP_COST = 0.01 |
104 _STARTUP_COST = 0.01 |
70 # The Windows worker is thread based. If tasks are CPU bound, threads |
105 # The Windows worker is thread based. If tasks are CPU bound, threads |
224 os._exit(ret & 255) |
259 os._exit(ret & 255) |
225 pids.add(pid) |
260 pids.add(pid) |
226 selector = selectors.DefaultSelector() |
261 selector = selectors.DefaultSelector() |
227 for rfd, wfd in pipes: |
262 for rfd, wfd in pipes: |
228 os.close(wfd) |
263 os.close(wfd) |
229 selector.register(os.fdopen(rfd, 'rb'), selectors.EVENT_READ) |
264 selector.register(os.fdopen(rfd, 'rb', 0), selectors.EVENT_READ) |
230 |
265 |
231 def cleanup(): |
266 def cleanup(): |
232 signal.signal(signal.SIGINT, oldhandler) |
267 signal.signal(signal.SIGINT, oldhandler) |
233 waitforworkers() |
268 waitforworkers() |
234 signal.signal(signal.SIGCHLD, oldchldhandler) |
269 signal.signal(signal.SIGCHLD, oldchldhandler) |
238 try: |
273 try: |
239 openpipes = len(pipes) |
274 openpipes = len(pipes) |
240 while openpipes > 0: |
275 while openpipes > 0: |
241 for key, events in selector.select(): |
276 for key, events in selector.select(): |
242 try: |
277 try: |
243 res = util.pickle.load(key.fileobj) |
278 res = util.pickle.load(_blockingreader(key.fileobj)) |
244 if hasretval and res[0]: |
279 if hasretval and res[0]: |
245 retval.update(res[1]) |
280 retval.update(res[1]) |
246 else: |
281 else: |
247 yield res |
282 yield res |
248 except EOFError: |
283 except EOFError: |