Skip to content
24 changes: 19 additions & 5 deletions python/tk_desktop/rpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,13 @@ class RPCServerThread(threading.Thread):
list/dictionary are treated as args/kwargs for the function call.
"""

# FIXME: Any errors raised here when closing won't actually be caught by
# our tests, because the error happens in a separate thread. This can be solved
# by catching and storing the exception and then raising it in the join method
# as suggested here: https://stackoverflow.com/a/31614591/4223964
# This is currently not implemented because it raises errors in our tests
# that we at the time of writing don't have time to fix, but have no impact on user experience.

# timeout in seconds to wait for a request
LISTEN_TIMEOUT = 2

Expand Down Expand Up @@ -256,7 +263,7 @@ def wrapper(*args, **kwargs):
def run(self):
"""
Run the thread, accepting connections and then listening on them until
they are closed. Each message is a call into the function table.
they are closed. Each message is a call into the function table.
"""
logger.debug("server listening on '%s'", self.pipe)
while self._is_closed is False:
Expand All @@ -278,10 +285,17 @@ def run(self):
raise
ready = False
else:
# can use select on osx and linux
(rd, _, _) = select.select(
[self.server._listener._socket], [], [], self.LISTEN_TIMEOUT
)
# Can use select on OSX and Linux.
try:
(rd, _, _) = select.select(
[self.server._listener._socket], [], [], self.LISTEN_TIMEOUT
)
except select.error as e:
if "Bad file descriptor" in e.args:
Comment thread
jfboismenu marked this conversation as resolved.
# The socket was likely closed during this iteration of the loop
# so we should break out of the loop.
break
raise
ready = len(rd) > 0

if not ready:
Expand Down
5 changes: 5 additions & 0 deletions tests/test_rpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,11 @@ def server(fake_engine, request):

:returns: A RPCServerThread instance.
"""

# FIXME: Any errors raised here when closing won't actually be caught by
# our tests, because the error happens in a separate thread.
# See the FIX ME in the RPCServerThread class for further details.

server = RPCServerThread(fake_engine)
server.register_function(fake_engine.pass_arg)
server.register_function(fake_engine.pass_named_arg)
Expand Down