def accept(l): h = l._socket._host with errctx("accept %s %s" % (h.network(), l.addr())): while 1: _, _rx = select( l._down.recv, # 0 l._dialq.recv, # 1 ) if _ == 0: l._excDown() if _ == 1: req = _rx with h._sockmu: sk = h._allocFreeSocket() ack = chan() req._resp.send(Accept(sk.addr(), ack)) _, _rx = select( l._down.recv, # 0 ack.recv, # 1 ) if _ == 0: def purgesk(): err = ack.recv() if err is None: try: req._netsk.close() except: pass with h._sockmu: h._socketv[sk._port] = None go(purgesk) l._excDown() if _ == 1: err = _rx if err is not None: with h._sockmu: h._socketv[sk._port] = None continue c = conn(sk, req._from, req._netsk) with h._sockmu: sk.conn = c return c
def test_timer_stop(): tv = [] t10 = time.Timer(10 * dt) t2 = time.Timer(2 * dt) # will fire and cancel t3, tx5 t3 = time.Timer(3 * dt) # will be canceled tx5 = time.Ticker(5 * dt) # will be canceled while 1: _, _rx = select( t10.c.recv, # 0 t2.c.recv, # 1 t3.c.recv, # 2 tx5.c.recv, # 3 ) if _ == 0: tv.append(10) break if _ == 1: tv.append(2) t3.stop() tx5.stop() if _ == 2: tv.append(3) if _ == 3: tv.append(5) assert tv == [2, 10]
def _vnet_accept(n, src, dst, netconn): with n._hostmu: host = n._hostmap.get(dst.host) if host is None: raise net.gaierror('%s: no such host' % dst.host) host._sockmu.acquire() if dst.port >= len(host._socketv): host._sockmu.release() raise ErrConnRefused sk = host._socketv[dst.port] if sk is None or sk._listener is None: host._sockmu.release() raise ErrConnRefused l = sk._listener host._sockmu.release() resp = chan() req = dialReq(src, netconn, resp) _, _rx = select( l._down.recv, # 0 (l._dialq.send, req), # 1 ) if _ == 0: raise ErrConnRefused if _ == 1: return resp.recv()
def ready(ch): _, _rx = select( ch.recv, # 0 default, # 1 ) if _ == 0: return True if _ == 1: return False
def test_timer(): # start timers at x5, x7 and x11 intervals an verify that the timers fire # in expected sequence. The times when the timers fire do not overlap in # checked range because intervals are prime and chosen so that they start # overlapping only after 35 (=5·7). tv = [] # timer events Tstart = time.now() t23 = time.Timer(23 * dt) t5 = time.Timer(5 * dt) def _(): tv.append(7) t7f.reset(7 * dt) t7f = time.Timer(7 * dt, f=_) tx11 = time.Ticker(11 * dt) while 1: _, _rx = select( t23.c.recv, # 0 t5.c.recv, # 1 t7f.c.recv, # 2 tx11.c.recv, # 3 ) if _ == 0: tv.append(23) break if _ == 1: tv.append(5) t5.reset(5 * dt) if _ == 2: assert False, "t7f sent to channel; must only call func" if _ == 3: tv.append(11) Tend = time.now() assert (Tend - Tstart) >= 23 * dt assert tv == [5, 7, 5, 11, 7, 5, 5, 7, 11, 23]
def test_timer_misc(): tv = [] Tstart = time.now() c23 = time.after(23 * dt) c5 = time.after(5 * dt) def _(): tv.append(7) t7f.reset(7 * dt) t7f = time.after_func(7 * dt, _) cx11 = time.tick(11 * dt) while 1: _, _rx = select( c23.recv, # 0 c5.recv, # 1 t7f.c.recv, # 2 cx11.recv, # 3 ) if _ == 0: tv.append(23) break if _ == 1: tv.append(5) # NOTE 5 does not rearm in this test because there is no way to # rearm timer create by time.after(). if _ == 2: assert False, "t7f sent to channel; must only call func" if _ == 3: tv.append(11) Tend = time.now() assert (Tend - Tstart) >= 23 * dt assert tv == [5, 7, 11, 7, 7, 11, 23]
def test_rwmutex_lock_vs_rlock(unlock_via_downgrade): mu = sync.RWMutex() # Lock vs RLock l = [] # accessed as R R R ... R W R R R ... R Nr1 = 10 # Nreaders queued before W Nr2 = 15 # Nreaders queued after W mu.RLock() locked = chan(Nr1 + 1 * 3 + Nr2) # main <- R|W: mu locked rcont = chan() # main -> R: continue def R(): # readers mu.RLock() locked.send(('R', len(l))) rcont.recv() mu.RUnlock() for i in range(Nr1): go(R) # make sure all Nr1 readers entered mu.RLock for i in range(Nr1): assert locked.recv() == ('R', 0) # spawn W def W(): # 1 writer mu.Lock() time.sleep( Nr2 * dt) # give R2 readers more chance to call mu.RLock and run first locked.send('W') l.append('a') if not unlock_via_downgrade: locked.send('_WUnlock') mu.Unlock() else: locked.send('_WUnlockToRLock') mu.UnlockToRLock() time.sleep(Nr2 * dt) locked.send('_WRUnlock') mu.RUnlock() go(W) # spawn more readers to verify that Lock has priority over RLock time.sleep(1 * dt) # give W more chance to call mu.Lock first for i in range(Nr2): go(R) # release main rlock, make sure nor W nor more R are yet ready, and let all readers continue time.sleep((1 + 1) * dt) mu.RUnlock() time.sleep(1 * dt) for i in range(100): _, _rx = select( default, # 0 locked.recv, # 1 ) assert _ == 0 rcont.close() # W must get the lock first and all R2 readers only after it assert locked.recv() == 'W' if not unlock_via_downgrade: assert locked.recv() == '_WUnlock' else: assert locked.recv() == '_WUnlockToRLock' for i in range(Nr2): assert locked.recv() == ('R', 1) if unlock_via_downgrade: assert locked.recv() == '_WRUnlock'