[pypy-svn] r21608 - pypy/dist/pypy/tool

pedronis at codespeak.net pedronis at codespeak.net
Fri Dec 30 23:13:23 CET 2005


Author: pedronis
Date: Fri Dec 30 23:13:22 2005
New Revision: 21608

Added:
   pypy/dist/pypy/tool/isolate_slave.py   (contents, props changed)
   pypy/dist/pypy/tool/slaveproc.py   (contents, props changed)
Modified:
   pypy/dist/pypy/tool/isolate.py
Log:
switch to using popen directly for isolate. The problem is that threads used by execnet and Boehm
result in segfaults because obviously the hosting  cpython is not compiled in such a way that new threads 
are advertised to Boehm.



Modified: pypy/dist/pypy/tool/isolate.py
==============================================================================
--- pypy/dist/pypy/tool/isolate.py	(original)
+++ pypy/dist/pypy/tool/isolate.py	Fri Dec 30 23:13:22 2005
@@ -1,34 +1,5 @@
-import py
-import exceptions
-
-ISOLATE = """
-import sys
-import imp
-
-mod = channel.receive()
-if isinstance(mod, str):
-    mod = __import__(mod, {}, {}, ['__doc__'])
-else:
-    dir, name = mod
-    file, pathname, description = imp.find_module(name, [dir])
-    try:
-        mod = imp.load_module(name, file, pathname, description)
-    finally:
-        if file:
-            file.close()    
-channel.send("loaded")
-while True:
-    func, args = channel.receive()
-    try:
-        res = getattr(mod, func)(*args)
-    except KeyboardInterrupt:
-        raise
-    except:
-        exc_type = sys.exc_info()[0] 
-        channel.send(('exc', (exc_type.__module__, exc_type.__name__)))
-    else:
-        channel.send(('ok', res))
-"""
+import exceptions, os
+from pypy.tool import slaveproc
 
 class IsolateException(Exception):
     pass
@@ -57,17 +28,17 @@
     _closed = False
 
     def __init__(self, module):
-        self.gw = py.execnet.PopenGateway()
-        chan = self.chan = self.gw.remote_exec(ISOLATE)
-        chan.send(module)
-        assert chan.receive() == "loaded"
+        self.slave = slaveproc.SlaveProcess(os.path.join(os.path.dirname(__file__),
+                                                         'isolate_slave.py'))
+        res = self.slave.cmd(('load', module))
+        assert res == 'loaded'
 
     def __getattr__(self, name):
         return IsolateInvoker(self, name)
 
     def _invoke(self, func, args):
-        self.chan.send((func, args))
-        status, value =  self.chan.receive()
+        status, value = self.slave.cmd(('invoke', (func, args)))
+        print 'OK'
         if status == 'ok':
             return value
         else:
@@ -79,8 +50,7 @@
 
     def _close(self):
         if not self._closed:
-            self.chan.close()
-            self.gw.exit()
+            self.slave.close()
             self._closed = True
 
     def __del__(self):

Added: pypy/dist/pypy/tool/isolate_slave.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/tool/isolate_slave.py	Fri Dec 30 23:13:22 2005
@@ -0,0 +1,41 @@
+import autopath
+import sys, imp
+from pypy.tool import slaveproc
+
+class IsolateSlave(slaveproc.Slave):
+    mod = None
+
+    def do_cmd(self, cmd):
+        cmd, data = cmd
+        if cmd == 'load':
+            assert self.mod is None
+            mod = data
+            if isinstance(mod, str):
+                mod = __import__(mod, {}, {}, ['__doc__'])
+            else:
+                dir, name = mod
+                file, pathname, description = imp.find_module(name, [dir])
+                try:
+                    mod = imp.load_module(name, file, pathname, description)
+                finally:
+                    if file:
+                        file.close()
+            self.mod = mod
+            return 'loaded'
+        elif cmd == 'invoke':
+            assert self.mod is not None
+            func, args = data
+            try:
+                res = getattr(self.mod, func)(*args)
+            except KeyboardInterrupt:
+                raise
+            except:
+                exc_type = sys.exc_info()[0] 
+                return ('exc', (exc_type.__module__, exc_type.__name__))
+            else:
+                return ('ok', res)
+        else:
+            return 'no-clue'
+
+if __name__ == '__main__':
+    IsolateSlave().do()

Added: pypy/dist/pypy/tool/slaveproc.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/tool/slaveproc.py	Fri Dec 30 23:13:22 2005
@@ -0,0 +1,52 @@
+import os, struct, marshal, sys
+
+class Exchange(object):
+    def __init__(self, inp, out):
+        self.out = out
+        self.inp = inp
+
+    def send(self, data):
+        s = marshal.dumps(data)
+        h = struct.pack('L', len(s))
+        self.out.write(h+s)
+        self.out.flush()
+
+    def recv(self):
+        HSIZE = struct.calcsize('L')
+        h = self.inp.read(HSIZE)
+        if len(h) < HSIZE:
+            raise EOFError
+        size = struct.unpack('L', h)[0]
+        s = self.inp.read(size)
+        if len(s) < size:
+            raise EOFError
+        return marshal.loads(s)
+
+class SlaveProcess(object):
+
+    def __init__(self, slave_impl):
+        inp, out = os.popen2('%s -u %s' % (sys.executable, os.path.abspath(slave_impl)))
+        self.exchg = Exchange(out, inp)
+
+    def cmd(self, data):
+        self.exchg.send(data)
+        return self.exchg.recv()
+
+    def close(self):
+        assert self.cmd(None) == 'done'
+
+class Slave(object):
+
+    def do_cmd(self, data):
+        raise NotImplementedError
+
+    def do(self):
+        exchg = Exchange(sys.stdin, sys.stdout)
+        while True:
+            cmd = exchg.recv()
+            if cmd is None:
+                exchg.send('done')
+                break
+            result = self.do_cmd(cmd)
+            exchg.send(result)
+        



More information about the Pypy-commit mailing list