Skip to content

Commit 2814ae9

Browse files
committed
gateway: Cache rinfo for main_thread_only
Fix a bug triggered by pytest-cov when it tries to call _rinfo after the gateway is already busy with a remote_exec call: pytest-dev/pytest-xdist#1070 (comment)
1 parent 4999a10 commit 2814ae9

File tree

2 files changed

+37
-0
lines changed

2 files changed

+37
-0
lines changed

src/execnet/gateway.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,11 @@ def __init__(self, io: IO, spec: XSpec) -> None:
3131
super().__init__(io=io, id=spec.id, _startcount=1)
3232
self.spec = spec
3333
self._initreceive()
34+
if self.execmodel.backend == "main_thread_only":
35+
# This will cause a deadlock if there is already a running
36+
# remote_exec, so cache the result before there are any
37+
# other remote_exec calls.
38+
self._rinfo()
3439

3540
@property
3641
def remoteaddress(self) -> str:

testing/test_gateway.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -645,3 +645,35 @@ def test_main_thread_only_concurrent_remote_exec_deadlock(
645645
ch.close()
646646
gw.exit()
647647
gw.join()
648+
649+
650+
def test_concurrent_rinfo(
651+
execmodel: gateway_base.ExecModel, makegateway: Callable[[str], Gateway]
652+
) -> None:
653+
gw = makegateway(f"execmodel={execmodel.backend}//popen")
654+
655+
try:
656+
ch = gw.remote_exec(
657+
"""
658+
import os, time
659+
time.sleep(1.5)
660+
channel.send(os.getpid())
661+
"""
662+
)
663+
# For main_thread_only _rinfo will deadlock unless the gateway
664+
# has cached the result earlier, but only if the above sleep
665+
# exceeds the 1 second grace period in the WorkerGateway
666+
# _local_schedulexec method.
667+
if execmodel.backend == "main_thread_only":
668+
assert hasattr(gw, "_cache_rinfo")
669+
rinfo = gw._rinfo()
670+
try:
671+
res = ch.receive()
672+
finally:
673+
ch.close()
674+
ch.waitclose()
675+
676+
assert res == rinfo.pid
677+
finally:
678+
gw.exit()
679+
gw.join()

0 commit comments

Comments
 (0)