def feed_block (self, b, height, verify=False): if b.prev_block != self.block_name: raise ValueError (b.prev_block, self.block_name) # assume coinbase is ok for now tx0 = b.transactions[0] reward0 = self.store_outputs (tx0) fees = 0 for i, tx in enumerate (b.transactions): if i == 0: continue # verify each transaction # first, we need the output script for each of the inputs input_sum = 0 for j in range (len (tx.inputs)): (outpoint, index), script, sequence = tx.inputs[j] amt, oscript = self.outpoints.pop_utxo (str(outpoint), index) #W ('.') if verify: tx.verify (j, oscript, b.timestamp) # XXX if it fails to verify, put it back! input_sum += amt output_sum = self.store_outputs (tx) fees += input_sum - output_sum self.total -= input_sum if self.do_yields and i % 50 == 0: coro.yield_slice() self.fees += fees reward1 = compute_reward (height) if reward1 + fees != reward0: lost = (reward1 + fees) - reward0 #W ('reward mismatch height=%d lost=%s\n' % (height, lost)) self.lost += lost self.height = height self.block_name = b.name
def _test_ownership(self, m): # This trylock "fails". self.assertTrue(m.trylock()) # This one blocks. self.assertTrue(m.lock()) # Bounce back to other thread. coro.yield_slice()
def test_exception_stomp(self): # Pyrex had a bug where if it raised an exception it would stomp on # the "current" exception on the Python stack. s = coro.semaphore(0) def blocker(): s.acquire(1) t1 = coro.spawn(blocker) coro.yield_slice() # Mark the thread as scheduled. t1.shutdown() def raiser(): try: raise ValueError(3) except ValueError: # This will attempt to schedule t1 which will result in a # ScheduleError getting raised and caught within the release # code. s.release(1) # This should re-raise ValueError. But with the bug, it was # re-raising ScheduleError. raise self.assertRaises(ValueError, raiser)
def feed_block(self, b, height, verify=False): if b.prev_block != self.block_name: raise ValueError(b.prev_block, self.block_name) # assume coinbase is ok for now tx0 = b.transactions[0] reward0 = self.store_outputs(tx0) fees = 0 for i, tx in enumerate(b.transactions): if i == 0: continue # verify each transaction # first, we need the output script for each of the inputs input_sum = 0 for j in range(len(tx.inputs)): (outpoint, index), script, sequence = tx.inputs[j] amt, oscript = self.outpoints.pop_utxo(str(outpoint), index) #W ('.') if verify: tx.verify(j, oscript, b.timestamp) # XXX if it fails to verify, put it back! input_sum += amt output_sum = self.store_outputs(tx) fees += input_sum - output_sum self.total -= input_sum if self.do_yields and i % 50 == 0: coro.yield_slice() self.fees += fees reward1 = compute_reward(height) if reward1 + fees != reward0: lost = (reward1 + fees) - reward0 #W ('reward mismatch height=%d lost=%s\n' % (height, lost)) self.lost += lost self.height = height self.block_name = b.name
def save_state (self): from coro.asn1.data_file import DataFileWriter from __main__ import G save_path = os.path.join (G.args.base, self.save_path) f = open (save_path + '.tmp', 'wb') df = DataFileWriter (f) t0 = timer() df.write_object ([ self.cache_version, self.height, str(self.block_name), self.total, self.lost, self.fees, len(self.outpoints) ]) n = 0 for item in self.outpoints: df.write_object (item) n += 1 if n % 1000 == 999: coro.yield_slice() f.close() os.rename (save_path + '.tmp', save_path) W ('[saved outpoints %d/%d entries %.02fs]' % (len(self.outpoints), n, t0.end()))
def _start_listener(self): s = coro.tcp_sock() s.bind(('127.0.0.1', 0)) s.listen(5) addr = s.getsockname() self.port = addr[1] self._dummy_thread = coro.spawn(self._dummy_listener, s) coro.yield_slice()
def test_readv(self): """Test readv.""" global do_sleeps def testit(family, address, block_sends, block_receives, expected_results): s = coro.make_socket(family, socket.SOCK_STREAM) server.block_sends = block_sends coro.with_timeout(5, s.connect, (address, server.port)) blocks = coro.with_timeout(5, s.readv, block_receives) self.assertEqual(len(blocks), len(expected_results)) for block, expected_block in zip(blocks, expected_results): self.assertEqual(block, expected_block) to_test = [(socket.AF_INET, '127.0.0.1')] if coro.has_ipv6(): to_test.append((socket.AF_INET6, '::1')) else: sys.stderr.write('Warning: No IPv6 support; skipping tests\n') for family, address in to_test: server = TestServer() server_thread = coro.spawn(server.serve, family, address) # Give the server a chance to start. coro.yield_slice() # Different levels of greediness. for greediness in (1024, 1): coro.current().set_max_selfish_acts(greediness) # Do it once without sleeps, once with sleeps. for sleep in (False, True): do_sleeps = sleep testit(family, address, (5, 19, 3, 8), (5, 19, 3, 8), ('01234', '0123456789012345678', '012', '01234567')) testit(family, address, (5, 19, 3, 8), (24, 3, 8), ('012340123456789012345678', '012', '01234567')) testit(family, address, (5, 19, 3, 8), (2, 3, 19, 3, 8), ('01', '234', '0123456789012345678', '012', '01234567')) testit(family, address, (5, 5), (1, 1, 1, 1, 1, 1, 1, 1, 1, 1), ('0', '1', '2', '3', '4', '0', '1', '2', '3', '4')) testit(family, address, (1, 1, 1, 1, 1, 1, 1, 1, 1, 1), (5, 5), ('00000', '00000')) testit(family, address, (10, ), (5, ), ('01234', )) testit(family, address, (5, ), (10, ), ('01234', )) testit(family, address, (), (), ()) testit(family, address, (), (5, 2, 8), ()) testit(family, address, (5, 9), (5, 10), ('01234', '012345678')) testit(family, address, (5, 9), (5, 5, 3, 7), ('01234', '01234', '567', '8')) testit(family, address, (5, 5), (5, 5, 10), ('01234', '01234')) testit(family, address, (5, ), (6, ), ('01234', )) testit(family, address, (512 * 1024, ), (512 * 1024, ), (big_block[:512 * 1024], )) server_thread.raise_exception(coro.Shutdown)
def test_unlock_resume(self): """Test that unlock resume.""" m = coro.mutex() coro.spawn(self._test_unlock_resume, m) coro.yield_slice() # This will block, bounce over to other thread. self.assertTrue(m.lock()) self.assertTrue(m.has_lock()) self.assertFalse(m.unlock()) self.assertFalse(m.has_lock())
def tak2 (x, y, z): coro.yield_slice() if y >= x: return z else: return tak2 ( tak2 (x - 1, y, z), tak1 (y - 1, z, x), tak1 (z - 1, x, y) )
def test_wait_for_interrupt_submitted(self): # Test KEVENT_STATUS_SUBMITTED proc = coro_process.spawn_job_bg('sleep 30') def waiter(): proc.wait() waiter_thread = coro.spawn(waiter) coro.yield_slice() # Waiter has submitted its kevent. # Interrupt it before it fires. waiter_thread.shutdown() coro.yield_slice()
def test_with_timeout(self): def go(): print "timer" with self.assertRaises(coro.TimeoutError): # coro.with_timeout(2, coro.sleep_relative, 4) coro.with_timeout(2, coro.waitpid, os.getpid()) print "foo" coro.spawn(go) for i in range(5): coro.yield_slice() coro.sleep_relative(1)
def test_with_timeout (self): def go(): print "timer" with self.assertRaises(coro.TimeoutError): # coro.with_timeout(2, coro.sleep_relative, 4) coro.with_timeout(2, coro.waitpid, os.getpid()) print "foo" coro.spawn(go) for i in range(5): coro.yield_slice() coro.sleep_relative(1)
def test_with_timeout(self): def serve (port): s = coro.tcp_sock() s.bind (('', port)) s.listen (5) with self.assertRaises(coro.TimeoutError): conn, addr = coro.with_timeout(1, s.accept) # do this a second time to make sure no SimultaneousErrors occur with self.assertRaises(coro.TimeoutError): conn, addr = coro.with_timeout(1, s.accept) coro.spawn(serve, 8100) coro.yield_slice() coro.sleep_relative(3)
def test_local(self): """Test thread-local storage.""" self.t1_cv = coro.condition_variable() self.t2_cv = coro.condition_variable() self.shared = coro.ThreadLocal() self.shared.x = 1 t1 = coro.spawn(self.t1) t2 = coro.spawn(self.t2) # Let them run. coro.yield_slice() self.t1_cv.wake_one() # Let t1 run. coro.yield_slice() self.assertEqual(self.shared.x, 1) self.t2_cv.wake_one() # Let t2 run. coro.yield_slice() self.assertEqual(self.shared.x, 1) self.t1_cv.wake_one() self.t2_cv.wake_one() coro.yield_slice() t1.join() t2.join() self.assertEqual(self.shared.x, 1) del self.shared
def test_with_timeout(self): def serve(port): s = coro.tcp_sock() s.bind(("", port)) s.listen(5) with self.assertRaises(coro.TimeoutError): conn, addr = coro.with_timeout(1, s.accept) # do this a second time to make sure no SimultaneousErrors occur with self.assertRaises(coro.TimeoutError): conn, addr = coro.with_timeout(1, s.accept) coro.spawn(serve, 8100) coro.yield_slice() coro.sleep_relative(3)
def test_writev(self): """Test writev.""" global send_buffer_size, recv_buffer_size big_block = '0123456789' * 1024 * 100 def testit(family, address, block_sends, expected_buffer_result, expected_return): global finished finished = coro.condition_variable() s = coro.make_socket(family, socket.SOCK_STREAM) s.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, send_buffer_size) coro.with_timeout(5, s.connect, (address, server.port)) blocks = [big_block[:size] for size in block_sends] rc = coro.with_timeout(5, s.writev, blocks) s.close() if finished is not None: coro.with_timeout(5, finished.wait) self.assertEqual(expected_buffer_result, current_buffer) self.assertEqual(expected_return, rc) # Setting the send/recv buffer size to 1 causes writev to indicate it # was only able to send 1 byte before blocking. This allows us to test # the "partial" buffer sent code path. to_test = [(socket.AF_INET, '127.0.0.1')] if coro.has_ipv6(): to_test.append((socket.AF_INET6, '::1')) else: sys.stderr.write('Warning: No IPv6 support; skipping tests\n') for family, address in to_test: for bufsize in (32768, 1): send_buffer_size = bufsize recv_buffer_size = bufsize server = TestServer() server_thread = coro.spawn(server.serve, family, address) # Give the server a chance to start. coro.yield_slice() for greediness in (1024, 1): coro.current().set_max_selfish_acts(greediness) testit(family, address, (), '', 0) testit(family, address, (5, 3, 7, 8), '01234012012345601234567', 23) # bufsize==1 is too slow and not necessary if bufsize != 1: testit(family, address, (512 * 1024, ), big_block[:512 * 1024], 512 * 1024) server_thread.raise_exception(coro.Shutdown)
def test_interrupt_sleeping_coro(self): """Test interrupting a thread in a sleep call.""" exception_raised = [False] def foo(): self.assertFalse(exception_raised[0]) try: coro.sleep_relative(3) except TestException: exception_raised[0] = True c = coro.spawn(foo) coro.yield_slice() c.raise_exception(TestException) coro.yield_slice() self.assertTrue(exception_raised[0])
def test_scheduled_staging_interrupt(self): """Test interrupting a thread that is scheduled and in the staging list.""" t = coro.get_now() + coro.ticks_per_sec*3 exception_raised = [False] def foo(): self.assertFalse(exception_raised[0]) try: coro.sleep_absolute(t) except TestException: exception_raised[0] = True c = coro.spawn(foo) coro.sleep_absolute(t) c.raise_exception(TestException) coro.yield_slice() self.assertTrue(exception_raised[0])
def test_wait_for_interrupt_new(self): # Test KEVENT_STATUS_NEW proc = coro_process.spawn_job_bg('sleep 30') def waiter(): proc.wait() waiter_thread = coro.spawn(waiter) def killer(): waiter_thread.shutdown() coro.spawn(killer) # Waiter should be scheduled to run. # It will add kevent to changelist, then yield. # Then killer should be scheduled to run next. It # will reschedule waiter with an exception. # Waiter should then wake up and hit the # KEVENT_STATUS_NEW cleanup code path. coro.yield_slice()
def test_scheduled_pending_interrupt(self): """Test interrupting a thread that is scheduled and in the pending list.""" exception_raised = [False] def foo(): self.assertFalse(exception_raised[0]) try: coro._yield() except TestException: exception_raised[0] = True c = coro.spawn(foo) coro.yield_slice() c.schedule() c.raise_exception(TestException) coro.yield_slice() self.assertTrue(exception_raised[0])
def test_writev(self): """Test writev.""" global send_buffer_size, recv_buffer_size big_block = '0123456789' * 1024 * 100 def testit(family, address, block_sends, expected_buffer_result, expected_return): global finished finished = coro.condition_variable() s = coro.make_socket(family, socket.SOCK_STREAM) s.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, send_buffer_size) coro.with_timeout(5, s.connect, (address, server.port)) blocks = [ big_block[:size] for size in block_sends ] rc = coro.with_timeout(5, s.writev, blocks) s.close() if finished is not None: coro.with_timeout(5, finished.wait) self.assertEqual(expected_buffer_result, current_buffer) self.assertEqual(expected_return, rc) # Setting the send/recv buffer size to 1 causes writev to indicate it # was only able to send 1 byte before blocking. This allows us to test # the "partial" buffer sent code path. to_test = [(socket.AF_INET, '127.0.0.1')] if coro.has_ipv6(): to_test.append((socket.AF_INET6, '::1')) else: sys.stderr.write('Warning: No IPv6 support; skipping tests\n') for family, address in to_test: for bufsize in (32768, 1): send_buffer_size = bufsize recv_buffer_size = bufsize server = TestServer() server_thread = coro.spawn(server.serve, family, address) # Give the server a chance to start. coro.yield_slice() for greediness in (1024, 1): coro.current().set_max_selfish_acts(greediness) testit(family, address, (), '', 0) testit(family, address, (5, 3, 7, 8), '01234012012345601234567', 23) # bufsize==1 is too slow and not necessary if bufsize != 1: testit(family, address, (512 * 1024,), big_block[:512*1024], 512*1024) server_thread.raise_exception(coro.Shutdown)
def test_readv(self): """Test readv.""" global do_sleeps def testit(family, address, block_sends, block_receives, expected_results): s = coro.make_socket(family, socket.SOCK_STREAM) server.block_sends = block_sends coro.with_timeout(5, s.connect, (address, server.port)) blocks = coro.with_timeout(5, s.readv, block_receives) self.assertEqual(len(blocks), len(expected_results)) for block, expected_block in zip(blocks, expected_results): self.assertEqual(block, expected_block) to_test = [(socket.AF_INET, '127.0.0.1')] if coro.has_ipv6(): to_test.append((socket.AF_INET6, '::1')) else: sys.stderr.write('Warning: No IPv6 support; skipping tests\n') for family, address in to_test: server = TestServer() server_thread = coro.spawn(server.serve, family, address) # Give the server a chance to start. coro.yield_slice() # Different levels of greediness. for greediness in (1024, 1): coro.current().set_max_selfish_acts(greediness) # Do it once without sleeps, once with sleeps. for sleep in (False, True): do_sleeps = sleep testit(family, address, (5, 19, 3, 8), (5, 19, 3, 8), ('01234', '0123456789012345678', '012', '01234567')) testit(family, address, (5, 19, 3, 8), (24, 3, 8), ('012340123456789012345678', '012', '01234567')) testit(family, address, (5, 19, 3, 8), (2, 3, 19, 3, 8), ('01', '234', '0123456789012345678', '012', '01234567')) testit(family, address, (5, 5), (1, 1, 1, 1, 1, 1, 1, 1, 1, 1), ('0', '1', '2', '3', '4', '0', '1', '2', '3', '4')) testit(family, address, (1, 1, 1, 1, 1, 1, 1, 1, 1, 1), (5, 5), ('00000', '00000')) testit(family, address, (10,), (5,), ('01234',)) testit(family, address, (5,), (10,), ('01234',)) testit(family, address, (), (), ()) testit(family, address, (), (5, 2, 8), ()) testit(family, address, (5, 9), (5, 10), ('01234', '012345678')) testit(family, address, (5, 9), (5, 5, 3, 7), ('01234', '01234', '567', '8')) testit(family, address, (5, 5), (5, 5, 10), ('01234', '01234')) testit(family, address, (5,), (6,), ('01234',)) testit(family, address, (512*1024,), (512*1024,), (big_block[:512*1024],)) server_thread.raise_exception(coro.Shutdown)
def test_scheduled_staging_interrupt(self): """Test interrupting a thread that is scheduled and in the staging list.""" t = coro.get_now() + coro.ticks_per_sec * 3 exception_raised = [False] def foo(): self.assertFalse(exception_raised[0]) try: coro.sleep_absolute(t) except TestException: exception_raised[0] = True c = coro.spawn(foo) coro.sleep_absolute(t) c.raise_exception(TestException) coro.yield_slice() self.assertTrue(exception_raised[0])
def add_block (self, b): self.ready[b.prev_block] = b if b.name in self.requested: self.requested.remove (b.name) # we may have several blocks waiting to be chained # in by the arrival of a missing link... while 1: if G.block_db.has_key (b.prev_block) or (b.prev_block == block_db.ZERO_NAME): del self.ready[b.prev_block] self.block_to_db (b.name, b) if self.ready.has_key (b.name): b = self.ready[b.name] else: break else: break coro.yield_slice()
def test_exception_stomp2(self): # Pyrex had a bug where calling a function within an exception handler, # and that function raised and caught an exception, it would stomp on # the current exception, so re-raising would raise the wrong exception. s = coro.semaphore(0) def blocker(): s.acquire(1) t1 = coro.spawn(blocker) t2 = coro.spawn(blocker) coro.yield_slice() # Make t1 scheduled. s.release(1) # Interrupt t1, it will try to schedule t2, but that will fail. t1.shutdown() # Cause t2 to be scheduled. t2.shutdown() coro.yield_slice()
def feed_tx (self, index, tx, timestamp, verify=False): input_sum = 0 for j in range (len (tx.inputs)): (outpoint, index), script, sequence = tx.inputs[j] outstr = str(outpoint) amt, lock_script = self.outpoints.pop_utxo (outstr, index) if verify: try: tx.verify (j, lock_script, timestamp) except VerifyError: self.outpoints.new_entry (outstr, [(index, amt, lock_script)]) raise input_sum += amt if self.do_yields and j % 20 == 19: coro.yield_slice() output_sum = self.store_outputs (tx) return input_sum, output_sum
def _test(self, address): server = TestServer() server_thread = coro.spawn(server.serve, address) # Give the server a chance to start. coro.yield_slice() self.assertEqual(server.bound_ip, address) sock = coro.make_socket_for_ip(address, socket.SOCK_STREAM) sock.connect((address, server.port)) coro.yield_slice() # Double checking that everyone thinks they're connected # to the same peer self.assertEqual(server.accepted_from, address) self.assertEqual(sock.getpeername()[0], server.accepted_from) self.do_work(sock)
def feed_tx(self, index, tx, timestamp, verify=False): input_sum = 0 for j in range(len(tx.inputs)): (outpoint, index), script, sequence = tx.inputs[j] outstr = str(outpoint) amt, lock_script = self.outpoints.pop_utxo(outstr, index) if verify: try: tx.verify(j, lock_script, timestamp) except VerifyError: self.outpoints.new_entry(outstr, [(index, amt, lock_script)]) raise input_sum += amt if self.do_yields and j % 20 == 19: coro.yield_slice() output_sum = self.store_outputs(tx) return input_sum, output_sum
def _test(self, address, family): server = TestServer() server_thread = coro.spawn(server.serve, address, family) # Give the server a chance to start. coro.yield_slice() self.assertEqual(server.bound_ip, address) sock = coro.make_socket(family, socket.SOCK_STREAM) sock.connect((address, server.port)) coro.yield_slice() # Double checking that everyone thinks they're connected # to the same peer self.assertEqual(server.accepted_from, address) self.assertEqual(sock.getpeername()[0], server.accepted_from) self.do_work(sock)
def test_accept_many (self): global count server = TestServer() coro.spawn (server.serve, coro.AF.INET, '127.0.0.1') coro.yield_slice() def connect(): s = coro.make_socket (coro.AF.INET, socket.SOCK_STREAM) coro.with_timeout (5, s.connect, ('127.0.0.1', server.port)) howdy = coro.with_timeout (5, s.recv, 100) self.assertEqual (howdy, 'howdy!\r\n') count -= 1 if count == 0: server_thread.raise_exception(coro.Shutdown) coro.spawn (connect) coro.spawn (connect) coro.spawn (connect) count = 3
def test_cond_schedule_interrupt(self): """Test schedule then interrupt on condition variable.""" c = coro.condition_variable() self._resume_count = 0 threads = [] # Spawn some threads that will block and be interrupted. for unused in xrange(5): threads.append(coro.spawn(self._cond_block, c)) # Spawn a thread that we will not interrupt. no_interrupt_thread = coro.spawn(self._cond_block, c) coro.yield_slice() # Schedule all of the threads (except the no interrupt thread). c.wake_all() # Now interrupt them. for t in threads: t.shutdown() coro.yield_slice() # Verify that it ran. self.assertEqual(self._resume_count, 1)
def test_cond_interrupt_schedule(self): """Test interrupt then schedule on condition variable.""" c = coro.condition_variable() self._resume_count = 0 threads = [] # Spawn some threads that will block and be interrupted. for unused in xrange(5): threads.append(coro.spawn(self._cond_block, c)) # Spawn a thread that we will not interrupt. no_interrupt_thread = coro.spawn(self._cond_block, c) coro.yield_slice() # Cause an interrupt on these threads. for t in threads: t.shutdown() # Now try to get the non-interrupted thread to run. c.wake_all() coro.yield_slice() # Verify that it ran. self.assertEqual(self._resume_count, 1)
def test_read_block_interrupt_schedule(self): """Test read block interrupt then schedule on rw_lock.""" lock = coro.rw_lock() lock.write_lock() self._resume_count = 0 threads = [] # Spawn some threads that will block and be interrupted. for unused in xrange(5): threads.append(coro.spawn(self._read_block, lock)) # Spawn a thread that we will not interrupt. no_interrupt_thread = coro.spawn(self._read_block, lock) coro.yield_slice() # Cause an interrupt on these threads. for t in threads: t.shutdown() # Now try to get the non-interrupted thread to run. lock.write_unlock() coro.yield_slice() # Verify that it ran. self.assertEqual(self._resume_count, 1)
def test_write_block_schedule_interrupt(self): """Test write block schedule then interrupt on rw_lock.""" lock = coro.rw_lock() lock.read_lock() self._resume_count = 0 threads = [] # Spawn some threads that will block and be interrupted. for unused in xrange(5): threads.append(coro.spawn(self._write_block, lock)) # Spawn a thread that we will not interrupt. no_interrupt_thread = coro.spawn(self._write_block, lock) coro.yield_slice() # Schedule all of the threads. lock.read_unlock() # Now interrupt them. for t in threads: t.shutdown() coro.yield_slice() # Verify that it ran. self.assertEqual(self._resume_count, 1)
def test_mutex_schedule_interrupt(self): """Test schedule then interrupt on mutex.""" m = coro.mutex() m.lock() self._resume_count = 0 threads = [] # Spawn some threads that will block and be interrupted. for unused in xrange(5): threads.append(coro.spawn(self._mutex_block, m)) # Spawn a thread that we will not interrupt. no_interrupt_thread = coro.spawn(self._mutex_block, m) coro.yield_slice() # Schedule all of the threads. m.unlock() # Now interrupt them. for t in threads: t.shutdown() coro.yield_slice() # Verify that it ran. self.assertEqual(self._resume_count, 1)
def test_isem_schedule_interrupt(self): """Test schedule then interrupt on inverted semaphore.""" s = coro.inverted_semaphore() s.acquire(1) self._resume_count = 0 threads = [] # Spawn some threads that will block and be interrupted. for unused in xrange(5): threads.append(coro.spawn(self._isem_block, s)) # Spawn a thread that we will not interrupt. no_interrupt_thread = coro.spawn(self._isem_block, s) coro.yield_slice() # Schedule all of the threads. s.release(1) # Now interrupt them. for t in threads: t.shutdown() coro.yield_slice() # Verify that it ran. self.assertEqual(self._resume_count, 1)
def test_fired(self): s = coro.tcp_sock() s.connect(("127.0.0.1", self.port)) self._fired_blocker_socket = s # We need to somehow schedule two threads to both wake up on kevent at # the same time in a particular order. The first one will call close # on the socket of the second one. f = open("test_fire", "w") coro.set_handler((f.fileno(), coro.EVFILT.VNODE), self._fired_closer, fflags=coro.NOTE.DELETE) t2 = coro.spawn(self._fired_blocker) # t2.set_max_selfish_acts(1) # Yield to allow fired blocker to block. coro.yield_slice() # Now, cause threads blocked on kevents to get scheduled in a specific # order. os.unlink("test_fire") s.send("force send") # Let those threads run. coro.yield_slice()
def test_sem_interrupt_schedule(self): """Test interrupt then schedule on semaphore.""" s = coro.semaphore(1) s.acquire(1) self._resume_count = 0 threads = [] # Spawn some threads that will block and be interrupted. for unused in xrange(5): threads.append(coro.spawn(self._sem_block, s)) # Spawn a thread that we will not interrupt. no_interrupt_thread = coro.spawn(self._sem_block, s) coro.yield_slice() # Cause an interrupt on these threads. for t in threads: t.shutdown() # Now try to get the non-interrupted thread to run. s.release(1) coro.yield_slice() # Verify that it ran. self.assertEqual(self._resume_count, 1)
def test_sem_schedule_interrupt(self): """Test schedule then interrupt on semaphore.""" s = coro.semaphore(5) s.acquire(5) self._resume_count = 0 threads = [] # Spawn some threads that will block and be interrupted. for unused in xrange(5): threads.append(coro.spawn(self._sem_block, s)) # Spawn a thread that we will not interrupt. no_interrupt_thread = coro.spawn(self._sem_block, s) coro.yield_slice() # Schedule all of the threads (except the no interrupt thread). s.release(5) # Now interrupt them. for t in threads: t.shutdown() coro.yield_slice() # Verify that it ran. self.assertEqual(self._resume_count, 1)
def save_state(self): from coro.asn1.data_file import DataFileWriter from __main__ import G save_path = os.path.join(G.args.base, self.save_path) f = open(save_path + '.tmp', 'wb') df = DataFileWriter(f) t0 = timer() df.write_object([ self.cache_version, self.height, str(self.block_name), self.total, self.lost, self.fees, len(self.outpoints) ]) n = 0 for item in self.outpoints: df.write_object(item) n += 1 if n % 1000 == 999: coro.yield_slice() f.close() os.rename(save_path + '.tmp', save_path) LOG('saved outpoints', len(self.outpoints), n, t0.end())
def test_fired(self): s = coro.tcp_sock() s.connect(('127.0.0.1', self.port)) self._fired_blocker_socket = s # We need to somehow schedule two threads to both wake up on kevent at # the same time in a particular order. The first one will call close # on the socket of the second one. f = open('test_fire', 'w') coro.set_handler((f.fileno(), coro.EVFILT.VNODE), self._fired_closer, fflags=coro.NOTE.DELETE) t2 = coro.spawn(self._fired_blocker) #t2.set_max_selfish_acts(1) # Yield to allow fired blocker to block. coro.yield_slice() # Now, cause threads blocked on kevents to get scheduled in a specific # order. os.unlink('test_fire') s.send('force send') # Let those threads run. coro.yield_slice()
def test_sem_buildup(self): """Test semaphore waiting buildup.""" # There was a bad bug once where the _waiting list got really big, # and a lot of interrupts was causing a lot of thrashing of the # _waiting list. s = coro.semaphore(1) s.acquire(1) self._resume_count = 0 threads = [] # Spawn some threads that will block and be interrupted. for unused in xrange(5): threads.append(coro.spawn(self._sem_block, s)) coro.yield_slice() self.assertEqual(len(s._waiting), 5) # Now interrupt them. for t in threads: t.shutdown() self.assertEqual(len(s._waiting), 5) # Now try to release. s.release(1) self.assertEqual(len(s._waiting), 0) coro.yield_slice() self.assertEqual(self._resume_count, 0)