Commits

Ronny Pfannschmidt committed 57cca20

linecache lock patch

  • Participants
  • Parent commits 2a0f875

Comments (0)

Files changed (4)

+# HG changeset patch
+# Parent da6994ca8402d9d29a367ed312cce0717ea46dad
+protect linecache.updatecache with a threading.Lock, fixes #5
+
+diff --git a/execnet/gateway.py b/execnet/gateway.py
+--- a/execnet/gateway.py
++++ b/execnet/gateway.py
+@@ -6,10 +6,19 @@ gateway code for initiating popen, socke
+ import sys, os, inspect, types, linecache
+ import textwrap
+ import execnet
+-from execnet.gateway_base import Message, Popen2IO, serialize
++from execnet.gateway_base import Message, Popen2IO, serialize, threading
+ from execnet import gateway_base
+ importdir = os.path.dirname(os.path.dirname(execnet.__file__))
+ 
++linecache_lock = threading.Lock()
++
++def linecache_updatecache(filename):
++    linecache_lock.acquire()
++    try:
++        linecache.updatecache(filename)
++    finally:
++        linecache_lock.release()
++
+ class Gateway(gateway_base.BaseGateway):
+     """ Gateway to a local or remote Python Intepreter. """
+ 
+@@ -110,7 +119,7 @@ class Gateway(gateway_base.BaseGateway):
+         """
+         call_name = None
+         if isinstance(source, types.ModuleType):
+-            linecache.updatecache(inspect.getsourcefile(source))
++            linecache_updatecache(inspect.getsourcefile(source))
+             source = inspect.getsource(source)
+         elif isinstance(source, types.FunctionType):
+             call_name = source.__name__
+linecache
 io-wait-kill
 io-creation-split
 bootstrap-split
 socket-io-creation-split
 io-on-remote
 topologic-shutdown
+test-remote-shutdown
+stash
+# HG changeset patch
+# Parent 8d5b1ff1deffedfb230448345aafcfee279c9f51
+diff --git a/execnet/gateway_base.py b/execnet/gateway_base.py
+--- a/execnet/gateway_base.py
++++ b/execnet/gateway_base.py
+@@ -698,9 +698,15 @@ class BaseGateway(object):
+         pass
+ 
+     def _send(self, msgcode, channelid=0, data=bytes()):
+-        header = struct.pack('!bii', msgcode, channelid, len(data))
+-        self._io.write(header+data)
+-        self._trace('sent', Message(msgcode, channelid, data))
++        message = Message(msgcode, channelid, data)
++        try:
++            message.to_io(self._io)
++            self._trace('sent', message)
++        except (IOError, ValueError):
++            e = sys.exc_info()[1]
++            self._trace('failed to send', message, e)
++            raise
++
+ 
+     def _local_schedulexec(self, channel, sourcetask):
+         channel.close("execution disallowed")
+diff --git a/testing/test_termination.py b/testing/test_termination.py
+--- a/testing/test_termination.py
++++ b/testing/test_termination.py
+@@ -112,3 +112,24 @@ def test_terminate_implicit_does_trykill
+     lines = [x for x in err.splitlines()
+                if '*sys-package' not in x]
+     assert not lines or "Killed" in err
++
++
++def test_master_killed():
++    group = execnet.Group()
++    master = group.makegateway('popen//id=master')
++    channel = master.remote_exec('channel.send(channel.receive())')
++    master._io.kill()
++    master._io.wait()
++    channel.send(1)
++    channel.receive(10)
++
++    group.terminate()
++
++
++def test_proxyed_slave_termination():
++    group = execnet.Group()
++    master = group.makegateway('popen//id=master')
++    watched = group.makegateway('popen//id=watched//via=master')
++    master.exit()
++    group.terminate()
++

File test-remote-shutdown

+# HG changeset patch
+# Parent 4f8c04469c761884cf3843b68ce0561884950c1d
+test how a remote gateway shuts down when its proxying gateway dies
+