def test_reset (self): evt = Event() # calling reset before send should throw self.assertRaises(AssertionError, evt.reset) value = 'some stuff' def send_to_event (): evt.send(value) spawn_n(send_to_event) self.assertEqual(evt.wait(), value) # now try it again, and we should get the same exact value, # and we shouldn't be allowed to resend without resetting value2 = 'second stuff' self.assertRaises(AssertionError, evt.send, value2) self.assertEqual(evt.wait(), value) # reset and everything should be happy evt.reset() def send_to_event2 (): evt.send(value2) spawn_n(send_to_event2) self.assertEqual(evt.wait(), value2)
def test_waiting_for_event (self): evt = Event() value = 'some stuff' def send_to_event (): evt.send(value) spawn_n(send_to_event) self.assertEqual(evt.wait(), value)
def starmap (self, function, iterable): """This is the same as :func:`itertools.starmap`, except that *func* is executed in a separate green thread for each item, with the concurrency limited by the pool's size. In operation, starmap consumes a constant amount of memory, proportional to the size of the pool, and is thus suited for iterating over extremely long input lists. """ if function is None: function = lambda *a: a gi = GreenMap(self.size) greenthread.spawn_n(self._do_map, function, iterable, gi) return gi
def test_waiting_for_event_timeout (self): evt = Event() def send_to_event (): sleep(10) evt.send(0) spawn_n(send_to_event) try: evt.wait(timeout = 0.5) except Timeout: pass except: self.fail('Timeout exception not raised') else: self.fail('Timeout exception not raised')
def test_kill_n(self): gt = spawn_n(passthru, 7) kill(gt) self.assert_dead(gt) sleep(0.001) self.assertEquals(_g_results, []) kill(gt) self.assert_dead(gt)
def test_kill_n (self): gt = spawn_n(passthru, 7) kill(gt) self.assert_dead(gt) sleep(0.001) self.assertEquals(_g_results, []) kill(gt) self.assert_dead(gt)
def _test_multiple_waiters (self, exception): evt = Event() value = 'some stuff' results = [] def wait_on_event (i_am_done): evt.wait() results.append(True) i_am_done.send() if exception: raise Exception() waiters = [] count = 5 for i in range(count): waiters.append(Event()) spawn_n(wait_on_event, waiters[-1]) sleep() # allow spawns to start executing evt.send() for w in waiters: w.wait() self.assertEqual(len(results), count)
def spawn_n (self, function, *args, **kwargs): """Create a greenthread to run the *function*, the same as :meth:`spawn`. The difference is that :meth:`spawn_n` returns None; the results of *function* are not retrievable. """ # if reentering an empty pool, don't try to wait on a coroutine freeing # itself -- instead, just execute in the current coroutine current = greenthread.getcurrent() if self.sem.locked() and current in self.coroutines_running: self._spawn_n_impl(function, args, kwargs, None) else: self.sem.acquire() g = greenthread.spawn_n(self._spawn_n_impl, function, args, kwargs, True) if not self.coroutines_running: self.no_coros_running = event.Event() self.coroutines_running.add(g)
def setup(): global _rfile, _wfile, _threads, _coro, _setup_already, _rspq if _setup_already: return else: _setup_already = True try: _rpipe, _wpipe = os.pipe() _wfile = GreenPipe(_wpipe, 'wb', 0) _rfile = GreenPipe(_rpipe, 'rb', 0) except (ImportError, NotImplementedError): # This is Windows compatibility -- use a socket instead of a pipe because # pipes don't really exist on Windows. import socket from evy import util sock = util.__original_socket__(socket.AF_INET, socket.SOCK_STREAM) sock.bind(('localhost', 0)) sock.listen(50) csock = util.__original_socket__(socket.AF_INET, socket.SOCK_STREAM) csock.connect(('localhost', sock.getsockname()[1])) nsock, addr = sock.accept() _rfile = GreenSocket(csock).makefile('rb', 0) _wfile = nsock.makefile('wb', 0) _rspq = Queue(maxsize=-1) assert _nthreads >= 0, "Can't specify negative number of threads" if _nthreads == 0: import warnings warnings.warn( "Zero threads in tpool. All tpool.execute calls will\ execute in main thread. Check the value of the environment \ variable EVENTLET_THREADPOOL_SIZE.", RuntimeWarning) for i in xrange(_nthreads): reqq = Queue(maxsize=-1) t = threading.Thread(target=tworker, name="tpool_thread_%s" % i, args=(reqq, )) t.setDaemon(True) t.start() _threads.append((reqq, t)) _coro = greenthread.spawn_n(tpool_trampoline)
def setup(): global _rfile, _wfile, _threads, _coro, _setup_already, _rspq if _setup_already: return else: _setup_already = True try: _rpipe, _wpipe = os.pipe() _wfile = GreenPipe(_wpipe, "wb", 0) _rfile = GreenPipe(_rpipe, "rb", 0) except (ImportError, NotImplementedError): # This is Windows compatibility -- use a socket instead of a pipe because # pipes don't really exist on Windows. import socket from evy import util sock = util.__original_socket__(socket.AF_INET, socket.SOCK_STREAM) sock.bind(("localhost", 0)) sock.listen(50) csock = util.__original_socket__(socket.AF_INET, socket.SOCK_STREAM) csock.connect(("localhost", sock.getsockname()[1])) nsock, addr = sock.accept() _rfile = GreenSocket(csock).makefile("rb", 0) _wfile = nsock.makefile("wb", 0) _rspq = Queue(maxsize=-1) assert _nthreads >= 0, "Can't specify negative number of threads" if _nthreads == 0: import warnings warnings.warn( "Zero threads in tpool. All tpool.execute calls will\ execute in main thread. Check the value of the environment \ variable EVENTLET_THREADPOOL_SIZE.", RuntimeWarning, ) for i in xrange(_nthreads): reqq = Queue(maxsize=-1) t = threading.Thread(target=tworker, name="tpool_thread_%s" % i, args=(reqq,)) t.setDaemon(True) t.start() _threads.append((reqq, t)) _coro = greenthread.spawn_n(tpool_trampoline)
def run_spawn_n_kw(): spawn_n(dummy, i=1)
def run_spawn_n(): spawn_n(dummy, 1)
def run_spawn_n (): spawn_n(dummy, 1) def run_spawn_n_kw (): spawn_n(dummy, i = 1)
def run_spawn_n_kw (): spawn_n(dummy, i = 1) best = benchmarks.measure_best(5, iters, 'pass', cleanup, run_spawn_n, run_spawn, run_spawn_n_kw)
def start_new_thread (function, args = (), kwargs = {}): g = greenthread.spawn_n(__thread_body, function, args, kwargs) return get_ident(g)
def reader(): try: while True: data = client.recv(1024) self.assert_(data) except socket.error, e: # we get an EBADF because client is closed in the same process # (but a different greenthread) if get_errno(e) != errno.EBADF: raise def closer(): client.close() reader = spawn(reader) spawn_n(closer) reader.wait() sender.wait() def test_ntoh(self): # This just checks that htons etc. are their own inverse, # when looking at the lower 16 or 32 bits. sizes = { socket.htonl: 32, socket.ntohl: 32, socket.htons: 16, socket.ntohs: 16 } for func, size in sizes.items(): mask = (1L << size) - 1 for i in (0, 1, 0xffff, ~0xffff, 2, 0x01234567, 0x76543210):
def test_n(self): gt = spawn_n(passthru, 2, b=3) self.assert_(not gt.dead) sleep(0) self.assert_(gt.dead) self.assertEquals(_g_results, [((2, ), {'b': 3})])
def reader (): try: while True: data = client.recv(1024) self.assert_(data) except socket.error, e: # we get an EBADF because client is closed in the same process # (but a different greenthread) if get_errno(e) != errno.EBADF: raise def closer (): client.close() reader = spawn(reader) spawn_n(closer) reader.wait() sender.wait() def test_ntoh (self): # This just checks that htons etc. are their own inverse, # when looking at the lower 16 or 32 bits. sizes = {socket.htonl: 32, socket.ntohl: 32, socket.htons: 16, socket.ntohs: 16} for func, size in sizes.items(): mask = (1L << size) - 1 for i in (0, 1, 0xffff, ~0xffff, 2, 0x01234567, 0x76543210): self.assertEqual(i & mask, func(func(i & mask)) & mask) swapped = func(mask)
def test_n (self): gt = spawn_n(passthru, 2, b = 3) self.assert_(not gt.dead) sleep(0) self.assert_(gt.dead) self.assertEquals(_g_results, [((2,), {'b': 3})])