1# 2# Analogue of `multiprocessing.connection` which uses queues instead of sockets 3# 4# multiprocessing/dummy/connection.py 5# 6# Copyright (c) 2006-2008, R Oudkerk 7# All rights reserved. 8# 9# Redistribution and use in source and binary forms, with or without 10# modification, are permitted provided that the following conditions 11# are met: 12# 13# 1. Redistributions of source code must retain the above copyright 14# notice, this list of conditions and the following disclaimer. 15# 2. Redistributions in binary form must reproduce the above copyright 16# notice, this list of conditions and the following disclaimer in the 17# documentation and/or other materials provided with the distribution. 18# 3. Neither the name of author nor the names of any contributors may be 19# used to endorse or promote products derived from this software 20# without specific prior written permission. 21# 22# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS "AS IS" AND 23# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 26# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32# SUCH DAMAGE. 33# 34 35__all__ = [ 'Client', 'Listener', 'Pipe' ] 36 37from queue import Queue 38 39 40families = [None] 41 42 43class Listener(object): 44 45 def __init__(self, address=None, family=None, backlog=1): 46 self._backlog_queue = Queue(backlog) 47 48 def accept(self): 49 return Connection(*self._backlog_queue.get()) 50 51 def close(self): 52 self._backlog_queue = None 53 54 address = property(lambda self: self._backlog_queue) 55 56 def __enter__(self): 57 return self 58 59 def __exit__(self, exc_type, exc_value, exc_tb): 60 self.close() 61 62 63def Client(address): 64 _in, _out = Queue(), Queue() 65 address.put((_out, _in)) 66 return Connection(_in, _out) 67 68 69def Pipe(duplex=True): 70 a, b = Queue(), Queue() 71 return Connection(a, b), Connection(b, a) 72 73 74class Connection(object): 75 76 def __init__(self, _in, _out): 77 self._out = _out 78 self._in = _in 79 self.send = self.send_bytes = _out.put 80 self.recv = self.recv_bytes = _in.get 81 82 def poll(self, timeout=0.0): 83 if self._in.qsize() > 0: 84 return True 85 if timeout <= 0.0: 86 return False 87 self._in.not_empty.acquire() 88 self._in.not_empty.wait(timeout) 89 self._in.not_empty.release() 90 return self._in.qsize() > 0 91 92 def close(self): 93 pass 94 95 def __enter__(self): 96 return self 97 98 def __exit__(self, exc_type, exc_value, exc_tb): 99 self.close() 100