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()
 |