67 lines
1.8 KiB
Python
67 lines
1.8 KiB
Python
|
import py
|
||
|
try:
|
||
|
from py.magic import greenlet
|
||
|
except (ImportError, RuntimeError), e:
|
||
|
py.test.skip(str(e))
|
||
|
|
||
|
|
||
|
class RGreenletBunch:
|
||
|
|
||
|
def __init__(self, gateway):
|
||
|
self.channel = gateway.remote_exec('''
|
||
|
from py.magic import greenlet
|
||
|
glob = {"greenlet": greenlet}
|
||
|
gids = {}
|
||
|
while True:
|
||
|
key, code, args = channel.receive()
|
||
|
if args is not None:
|
||
|
if code is not None:
|
||
|
def run(code=code):
|
||
|
exec code in glob, {}
|
||
|
gids[key] = greenlet(run)
|
||
|
result = gids[key].switch(*args)
|
||
|
channel.send(result)
|
||
|
else:
|
||
|
del gids[key]
|
||
|
''')
|
||
|
|
||
|
def greenlet(self, code):
|
||
|
return RGreenlet(self, code)
|
||
|
|
||
|
|
||
|
class RGreenlet:
|
||
|
|
||
|
def __init__(self, bunch, code):
|
||
|
self.channel = bunch.channel
|
||
|
self.code = str(py.code.Source(code))
|
||
|
|
||
|
def switch(self, *args):
|
||
|
self.channel.send((id(self), self.code, args))
|
||
|
self.code = None # only send over the code the first time
|
||
|
return self.channel.receive()
|
||
|
|
||
|
def __del__(self):
|
||
|
if self.code is None:
|
||
|
self.channel.send((id(self), None, None))
|
||
|
|
||
|
|
||
|
def test_rgreenlet():
|
||
|
gw = py.execnet.PopenGateway()
|
||
|
bunch = RGreenletBunch(gw)
|
||
|
g = bunch.greenlet('''
|
||
|
x = greenlet.getcurrent().parent.switch(42)
|
||
|
y = greenlet.getcurrent().parent.switch(x+1)
|
||
|
greenlet.getcurrent().parent.switch(y+2)
|
||
|
import os
|
||
|
greenlet.getcurrent().parent.switch(os.getpid())
|
||
|
''')
|
||
|
result = g.switch()
|
||
|
assert result == 42
|
||
|
result = g.switch(102)
|
||
|
assert result == 103
|
||
|
result = g.switch(-93)
|
||
|
assert result == -91
|
||
|
import os
|
||
|
result = g.switch()
|
||
|
assert result != os.getpid()
|