def loop(self, timeout = None, freq = None): if freq != None and self.bands[0][0] != freq: for fb in self.bands: if fb[0] == freq: self.bands.remove(fb) break else: fb = (freq, self.elp.addband(freq)) self.elp.useband(fb[1]) self.bands.insert(0, fb) self.endloop = False self.last_ts = MonoTime() if timeout != None: etime = self.last_ts.getOffsetCopy(timeout) while True: if len(self.signals_pending) > 0: self.dispatchSignals() if self.endloop: return if self.endloop: return self.dispatchTimers() if self.endloop: return if self.twasted * 2 > len(self.tlisteners): # Clean-up removed timers when their share becomes more than 50% self.tlisteners = [x for x in self.tlisteners if x.cb_func != None] heapify(self.tlisteners) self.twasted = 0 if (timeout != None and self.last_ts > etime) or self.endloop: self.endloop = False break self.elp.procrastinate() self.last_ts = MonoTime()
def loop(self, timeout=None): self.endloop = False self.last_ts = MonoTime() if timeout != None: etime = self.last_ts.getOffsetCopy(timeout) while True: if len(self.signals_pending) > 0: self.dispatchSignals() if self.endloop: return self.dispatchThreadCallbacks() if self.endloop: return self.dispatchTimers() if self.endloop: return if self.twasted * 2 > len(self.tlisteners): # Clean-up removed timers when their share becomes more than 50% self.tlisteners = [ x for x in self.tlisteners if x.cb_func != None ] heapify(self.tlisteners) self.twasted = 0 if (timeout != None and self.last_ts > etime) or self.endloop: self.endloop = False break self.elp.procrastinate() self.last_ts = MonoTime()
def testTimeoutAbsMono(): def test1(arguments, testnum, mtm): arguments['delay'] = mtm.offsetFromNow() print(testnum, arguments['delay']) arguments['test'] = True ED2.breakLoop() def test2(arguments, testnum, mtm): arguments['delay'] = mtm.offsetFromNow() print(testnum, arguments['delay']) arguments['test'] = 'bar' ED2.breakLoop() mt = MonoTime() arguments = {'test': False, 'delay': None} timeout_1 = TimeoutAbsMono(test1, mt, arguments, 'test1', mt) ED2.loop() assert (arguments['test']) assert (arguments['delay'] < 0.1) mt1 = mt.getOffsetCopy(0.1) mt2 = mt.getOffsetCopy(0.2) arguments = {'test': False, 'delay': None} timeout_1 = TimeoutAbsMono(test1, mt1, arguments, 'test2', mt1) timeout_2 = TimeoutAbsMono(test2, mt2, arguments, 'test3', mt2) timeout_1.cancel() ED2.loop() assert (arguments['test'] == 'bar') assert (arguments['delay'] < 0.1)
def testTimeout(): def test1(arguments, testnum): print(testnum) arguments['test'] = True ED2.breakLoop() def test2(arguments, testnum): print(testnum) arguments['test'] = 'bar' ED2.breakLoop() arguments = {'test': False} timeout_1 = Timeout(test1, 0, 1, arguments, 'test1') ED2.loop() assert (arguments['test']) timeout_1 = Timeout(test1, 0.1, 1, arguments, 'test2') timeout_2 = Timeout(test2, 0.2, 1, arguments, 'test3') timeout_1.cancel() ED2.loop() assert (arguments['test'] == 'bar') arguments = {'test': False} timeout_1 = TimeoutAbsMono(test1, MonoTime(), arguments, 'test4') ED2.loop() assert (arguments['test']) timeout_1 = TimeoutAbsMono(test1, MonoTime().getOffsetCopy(0.1), arguments, 'test5') timeout_2 = TimeoutAbsMono(test2, MonoTime().getOffsetCopy(0.2), arguments, 'test6') timeout_1.cancel() ED2.loop() assert (arguments['test'] == 'bar')
def testTimeoutAbsMono(): def test1(arguments, testnum, mtm): arguments['delay'] = mtm.offsetFromNow() print(testnum, arguments['delay']) arguments['test'] = True ED2.breakLoop() def test2(arguments, testnum, mtm): arguments['delay'] = mtm.offsetFromNow() print(testnum, arguments['delay']) arguments['test'] = 'bar' ED2.breakLoop() mt = MonoTime() arguments = {'test':False, 'delay':None} timeout_1 = TimeoutAbsMono(test1, mt, arguments, 'test1', mt) ED2.loop() assert(arguments['test']) assert(arguments['delay'] < 0.1) mt1 = mt.getOffsetCopy(0.1) mt2 = mt.getOffsetCopy(0.2) arguments = {'test':False, 'delay':None} timeout_1 = TimeoutAbsMono(test1, mt1, arguments, 'test2', mt1) timeout_2 = TimeoutAbsMono(test2, mt2, arguments, 'test3', mt2) timeout_1.cancel() ED2.loop() assert(arguments['test'] == 'bar') assert(arguments['delay'] < 0.1)
def __init__(self): EventDispatcher2.state_lock.acquire() if EventDispatcher2.ed_inum != 0: EventDispatcher2.state_lock.release() raise StdException('BZZZT, EventDispatcher2 has to be singleton!') EventDispatcher2.ed_inum = 1 EventDispatcher2.state_lock.release() self.tcbs_lock = Lock() self.tlisteners = [] self.slisteners = [] self.signals_pending = [] self.thread_cbs = [] self.last_ts = MonoTime() self.my_ident = get_ident()
def regTimer(self, timeout_cb, ival, nticks = 1, abs_time = False, *cb_params): self.last_ts = MonoTime() if nticks == 0: return if abs_time and not isinstance(ival, MonoTime): raise TypeError('ival is not MonoTime') el = EventListener() el.itime = self.last_ts.getCopy() el.cb_func = timeout_cb el.ival = ival el.nticks = nticks el.abs_time = abs_time el.cb_params = cb_params el.ed = self return el
def __init__(self, freq = 100.0): EventDispatcher2.state_lock.acquire() if EventDispatcher2.ed_inum != 0: EventDispatcher2.state_lock.release() raise StdException('BZZZT, EventDispatcher2 has to be singleton!') EventDispatcher2.ed_inum = 1 EventDispatcher2.state_lock.release() self.tcbs_lock = Lock() self.tlisteners = [] self.slisteners = [] self.signals_pending = [] self.last_ts = MonoTime() self.my_ident = get_ident() self.elp = ElPeriodic(freq) self.elp.CFT_enable(signal.SIGURG) self.bands = [(freq, 0),]
def process_reply(self, data, address, worker, rtime): try: cookie, result = data.split(None, 1) except: print('Rtp_proxy_client_udp.process_reply(): invalid response from %s: "%s"' % \ (str(address), data)) return cookie = cookie.decode() preq = self.pending_requests.pop(cookie, None) if preq == None: return preq.timer.cancel() if rtime <= preq.stime: # MonoTime as the name suggests is supposed to be monotonic, # so if we get response earlier than request went out something # is very wrong. Fail immediately. rtime_fix = MonoTime() raise AssertionError('cookie=%s: MonoTime stale/went' \ ' backwards (%f <= %f, now=%f)' % (cookie, rtime.monot, \ preq.stime.monot, rtime_fix.monot)) if preq.result_callback != None: result = result.decode() preq.result_callback(result.strip(), *preq.callback_parameters) # When we had to do retransmit it is not possible to figure out whether # or not this reply is related to the original request or one of the # retransmits. Therefore, using it to estimate delay could easily produce # bogus value that is too low or even negative if we cook up retransmit # while the original response is already in the queue waiting to be # processed. This should not be a big issue since UDP command channel does # not work very well if the packet loss goes to more than 30-40%. if preq.retransmits == 0: self.delay_flt.apply(rtime - preq.stime)
def run(self): maxemptydata = 100 while True: try: data, address = self.userv.skt.recvfrom(8192) if not data and address == None: # Ugly hack to detect socket being closed under us on Linux. # The problem is that even call on non-closed socket can # sometimes return empty data buffer, making AsyncReceiver # to exit prematurely. maxemptydata -= 1 if maxemptydata == 0: break continue else: maxemptydata = 100 rtime = MonoTime() except Exception as why: if isinstance(why, socket.error) and why.errno in (ECONNRESET, ENOTCONN, ESHUTDOWN): break if isinstance(why, socket.error) and why.errno in (EINTR,): continue else: print(datetime.now(), 'Udp_server: unhandled exception when receiving incoming data') print('-' * 70) traceback.print_exc(file = sys.stdout) print('-' * 70) sys.stdout.flush() sleep(1) continue if self.userv.uopts.family == socket.AF_INET6: address = ('[%s]' % address[0], address[1]) ED2.callFromThread(self.userv.handle_read, data, address, rtime) self.userv = None
def doCancel(self, t, rtime=None, req=None): if rtime == None: rtime = MonoTime() if t.r487 != None: self.sendResponse(t.r487, t, True) if t.cancel_cb != None: t.cancel_cb(rtime, req)
def __init__(self, data=None, rtime=None, origin=None): self.data = data if rtime == None: self.rtime = MonoTime() else: self.rtime = rtime self.seq = CCEventGeneric.seq CCEventGeneric.seq += 1 self.origin = origin
def getAcct(self): if self.disconnect_ts != None: disconnect_ts = self.disconnect_ts disconnected = True else: disconnect_ts = MonoTime() disconnected = False if self.connect_ts != None: return (disconnect_ts - self.connect_ts, self.connect_ts - self.setup_ts, True, disconnected) return (0, disconnect_ts - self.setup_ts, False, disconnected)
def newTransaction(self, msg, resp_cb = None, laddress = None, userv = None, \ cb_ifver = 1, compact = False, t = None): if t == None: t = SipTransaction() t.rtime = MonoTime() t.compact = compact t.method = msg.getMethod() t.cb_ifver = cb_ifver t.tid = msg.getTId(True, True) if t.tid in self.tclient: raise ValueError( 'BUG: Attempt to initiate transaction with the same TID as existing one!!!' ) t.tout = 0.5 t.fcode = None t.address = msg.getTarget() if userv == None: if laddress == None: t.userv = self.l4r.getServer(t.address) else: t.userv = self.l4r.getServer(laddress, is_local=True) else: t.userv = userv t.data = msg.localStr(*t.userv.uopts.getSIPaddr(), compact=t.compact) if t.method == 'INVITE': try: t.expires = msg.getHFBody('expires').getNum() if t.expires <= 0: t.expires = 300 except IndexError: t.expires = 300 t.needack = True t.ack = msg.genACK() t.cancel = msg.genCANCEL() else: t.expires = 32 t.needack = False t.ack = None t.cancel = None t.cancelPending = False t.resp_cb = resp_cb t.teA = Timeout(self.timerA, t.tout, 1, t) if resp_cb != None: t.r408 = msg.genResponse(408, 'Request Timeout') t.teB = Timeout(self.timerB, 32.0, 1, t) t.teC = None t.state = TRYING self.tclient[t.tid] = t self.transmitData(t.userv, t.data, t.address) if t.req_out_cb != None: t.req_out_cb(msg) return t
def send_raw(self, command, _recurse=0, stime=None): if _recurse > _MAX_RECURSE: raise Exception('Cannot reconnect: %s' % (str(self.userv.address), )) if self.s == None: self.connect() #print('%s.send_raw(%s)' % (id(self), command)) if stime == None: stime = MonoTime() while True: try: self.s.send(command.encode()) break except socket.error as why: if why.errno == EINTR: continue elif why.errno in (EPIPE, ENOTCONN, ECONNRESET): self.s = None return self.send_raw(command, _recurse + 1, stime) raise why while True: try: rval = self.s.recv(1024) if len(rval) == 0: self.s = None return self.send_raw(command, _MAX_RECURSE, stime) rval = rval.decode().strip() break except socket.error as why: if why.errno == EINTR: continue elif why.errno in (EPIPE, ENOTCONN, ECONNRESET): self.s = None return self.send_raw(command, _recurse + 1, stime) raise why rtpc_delay = stime.offsetFromNow() return (rval, rtpc_delay)
def send_raw(self, command, _recurse = 0, stime = None): if _recurse > _MAX_RECURSE: raise Exception('Cannot reconnect: %s' % (str(self.userv.address),)) if self.s == None: self.connect() #print('%s.send_raw(%s)' % (id(self), command)) if stime == None: stime = MonoTime() while True: try: self.s.send(command.encode()) break except socket.error as why: if why.errno == EINTR: continue elif why.errno in (EPIPE, ENOTCONN, ECONNRESET): self.s = None return self.send_raw(command, _recurse + 1, stime) raise why while True: try: rval = self.s.recv(1024) if len(rval) == 0: self.s = None return self.send_raw(command, _MAX_RECURSE, stime) rval = rval.decode().strip() break except socket.error as why: if why.errno == EINTR: continue elif why.errno in (EPIPE, ENOTCONN, ECONNRESET): self.s = None return self.send_raw(command, _recurse + 1, stime) raise why rtpc_delay = stime.offsetFromNow() return (rval, rtpc_delay)
def timerB(self, t): #print 'timerB', t t.teB = None if t.teA != None: t.teA.cancel() t.teA = None t.state = TERMINATED #print '2: Timeout(self.timerC, 32.0, 1, t)', t t.teC = Timeout(self.timerC, 32.0, 1, t) if t.resp_cb == None: return t.r408.rtime = MonoTime() if t.cb_ifver == 1: t.resp_cb(t.r408) else: t.resp_cb(t.r408, t)
def recvCommand(self, clim, cmd): args = cmd.split() cmd = args.pop(0).lower() if cmd == 'q': clim.close() return False if cmd == 'l': res = 'In-memory calls:\n' total = 0 for cc in self.ccmap: res += '%s: %s (' % (cc.cId, cc.state.sname) if cc.uaA != None: res += '%s %s:%d %s %s -> ' % (cc.uaA.state, cc.uaA.getRAddr0()[0], \ cc.uaA.getRAddr0()[1], cc.uaA.getCLD(), cc.uaA.getCLI()) else: res += 'N/A -> ' if cc.uaO != None: res += '%s %s:%d %s %s)\n' % (cc.uaO.state, cc.uaO.getRAddr0()[0], \ cc.uaO.getRAddr0()[1], cc.uaO.getCLI(), cc.uaO.getCLD()) else: res += 'N/A)\n' total += 1 res += 'Total: %d\n' % total clim.send(res) return False if cmd == 'lt': res = 'In-memory server transactions:\n' for tid, t in self.global_config['_sip_tm'].tserver.iteritems(): res += '%s %s %s\n' % (tid, t.method, t.state) res += 'In-memory client transactions:\n' for tid, t in self.global_config['_sip_tm'].tclient.iteritems(): res += '%s %s %s\n' % (tid, t.method, t.state) clim.send(res) return False if cmd in ('lt', 'llt'): if cmd == 'llt': mindur = 60.0 else: mindur = 0.0 ctime = MonoTime() res = 'In-memory server transactions:\n' for tid, t in self.global_config['_sip_tm'].tserver.iteritems(): duration = ctime - t.rtime if duration < mindur: continue res += '%s %s %s %s\n' % (tid, t.method, t.state, duration) res += 'In-memory client transactions:\n' for tid, t in self.global_config['_sip_tm'].tclient.iteritems(): duration = ctime - t.rtime if duration < mindur: continue res += '%s %s %s %s\n' % (tid, t.method, t.state, duration) clim.send(res) return False if cmd == 'd': if len(args) != 1: clim.send('ERROR: syntax error: d <call-id>\n') return False if args[0] == '*': self.discAll() clim.send('OK\n') return False dlist = [x for x in self.ccmap if str(x.cId) == args[0]] if len(dlist) == 0: clim.send('ERROR: no call with id of %s has been found\n' % args[0]) return False for cc in dlist: cc.disconnect() clim.send('OK\n') return False if cmd == 'r': if len(args) != 1: clim.send('ERROR: syntax error: r [<id>]\n') return False idx = int(args[0]) dlist = [x for x in self.ccmap if x.id == idx] if len(dlist) == 0: clim.send('ERROR: no call with id of %d has been found\n' % idx) return False for cc in dlist: if not cc.proxied: continue if cc.state == CCStateConnected: cc.disconnect(MonoTime().getOffsetCopy(-60)) continue if cc.state == CCStateARComplete: cc.uaO.disconnect(MonoTime().getOffsetCopy(-60)) continue clim.send('OK\n') return False clim.send('ERROR: unknown command\n') return False
def rDone(self, results): # Check that we got necessary result from Radius if len(results) != 2 or results[1] != 0: if isinstance(self.uaA.state, UasStateTrying): if self.challenge != None: event = CCEventFail((401, 'Unauthorized')) event.extra_header = self.challenge else: event = CCEventFail((403, 'Auth Failed')) self.uaA.recvEvent(event) self.state = CCStateDead return if self.global_config['acct_enable']: self.acctA = RadiusAccounting(self.global_config, 'answer', \ send_start = self.global_config['start_acct_enable'], lperiod = \ self.global_config.getdefault('alive_acct_int', None)) self.acctA.ms_precision = self.global_config.getdefault( 'precise_acct', False) self.acctA.setParams(self.username, self.cli, self.cld, self.cGUID, self.cId, self.remote_ip) else: self.acctA = FakeAccounting() # Check that uaA is still in a valid state, send acct stop if not isinstance(self.uaA.state, UasStateTrying): self.acctA.disc(self.uaA, MonoTime(), 'caller') return cli = [ x[1][4:] for x in results[0] if x[0] == 'h323-ivr-in' and x[1].startswith('CLI:') ] if len(cli) > 0: self.cli = cli[0] if len(self.cli) == 0: self.cli = None caller_name = [ x[1][5:] for x in results[0] if x[0] == 'h323-ivr-in' and x[1].startswith('CNAM:') ] if len(caller_name) > 0: self.caller_name = caller_name[0] if len(self.caller_name) == 0: self.caller_name = None credit_time = [x for x in results[0] if x[0] == 'h323-credit-time'] if len(credit_time) > 0: credit_time = int(credit_time[0][1]) else: credit_time = None if not '_static_route' in self.global_config: routing = [ x for x in results[0] if x[0] == 'h323-ivr-in' and x[1].startswith('Routing:') ] if len(routing) == 0: self.uaA.recvEvent( CCEventFail((500, 'Internal Server Error (2)'))) self.state = CCStateDead return routing = [B2BRoute(x[1][8:]) for x in routing] else: routing = [ self.global_config['_static_route'].getCopy(), ] rnum = 0 for oroute in routing: rnum += 1 max_credit_time = self.global_config.getdefault( 'max_credit_time', None) oroute.customize(rnum, self.cld, self.cli, credit_time, self.pass_headers, \ max_credit_time) if oroute.credit_time == 0 or oroute.expires == 0: continue self.routes.append(oroute) #print 'Got route:', oroute.hostport, oroute.cld if len(self.routes) == 0: self.uaA.recvEvent(CCEventFail((500, 'Internal Server Error (3)'))) self.state = CCStateDead return self.state = CCStateARComplete self.placeOriginate(self.routes.pop(0))
def __init__(self, next_retr, nretr, timer, command, result_callback, \ callback_parameters): self.stime = MonoTime() self.next_retr, self.triesleft, self.timer, self.command, self.result_callback, \ self.callback_parameters = next_retr, nretr, timer, command, \ result_callback, callback_parameters
from twisted.internet import reactor from sippy.Time.MonoTime import MonoTime def test1(arguments, testnum, mtm): arguments['delay'] = mtm.offsetFromNow() print testnum, arguments['delay'] arguments['test'] = True reactor.crash() def test2(arguments, testnum, mtm): arguments['delay'] = mtm.offsetFromNow() print testnum, arguments['delay'] arguments['test'] = 'bar' reactor.crash() mt = MonoTime() arguments = {'test': False, 'delay': None} timeout_1 = TimeoutAbsMono(test1, mt, arguments, 'test1', mt) reactor.run() assert (arguments['test']) assert (arguments['delay'] < 0.1) mt1 = mt.getOffsetCopy(0.1) mt2 = mt.getOffsetCopy(0.2) arguments = {'test': False, 'delay': None} timeout_1 = TimeoutAbsMono(test1, mt1, arguments, 'test2', mt1) timeout_2 = TimeoutAbsMono(test2, mt2, arguments, 'test3', mt2) timeout_1.cancel() reactor.run() assert (arguments['test'] == 'bar') assert (arguments['delay'] < 0.1)
class EventDispatcher2(Singleton): tlisteners = None slisteners = None endloop = False signals_pending = None twasted = 0 tcbs_lock = None last_ts = None my_ident = None state_lock = Lock() ed_inum = 0 elp = None bands = None def __init__(self, freq = 100.0): EventDispatcher2.state_lock.acquire() if EventDispatcher2.ed_inum != 0: EventDispatcher2.state_lock.release() raise StdException('BZZZT, EventDispatcher2 has to be singleton!') EventDispatcher2.ed_inum = 1 EventDispatcher2.state_lock.release() self.tcbs_lock = Lock() self.tlisteners = [] self.slisteners = [] self.signals_pending = [] self.last_ts = MonoTime() self.my_ident = get_ident() self.elp = ElPeriodic(freq) self.elp.CFT_enable(signal.SIGURG) self.bands = [(freq, 0),] def signal(self, signum, frame): self.signals_pending.append(signum) def regTimer(self, timeout_cb, ival, nticks = 1, abs_time = False, *cb_params): self.last_ts = MonoTime() if nticks == 0: return if abs_time and not isinstance(ival, MonoTime): raise TypeError('ival is not MonoTime') el = EventListener() el.itime = self.last_ts.getCopy() el.cb_func = timeout_cb el.ival = ival el.nticks = nticks el.abs_time = abs_time el.cb_params = cb_params el.ed = self return el def dispatchTimers(self): while len(self.tlisteners) != 0: el = self.tlisteners[0] if el.cb_func != None and el.etime > self.last_ts: # We've finished return el = heappop(self.tlisteners) if el.cb_func == None: # Skip any already removed timers self.twasted -= 1 continue if el.nticks == -1 or el.nticks > 1: # Re-schedule periodic timer if el.nticks > 1: el.nticks -= 1 if el.randomize_runs != None: ival = el.randomize_runs(el.ival) else: ival = el.ival el.etime.offset(ival) heappush(self.tlisteners, el) cleanup = False else: cleanup = True try: if not el.cb_with_ts: el.cb_func(*el.cb_params) else: el.cb_func(self.last_ts, *el.cb_params) except Exception as ex: if isinstance(ex, SystemExit): raise dump_exception('EventDispatcher2: unhandled exception when processing timeout event') if self.endloop: return if cleanup: el.cleanup() def regSignal(self, signum, signal_cb, *cb_params, **cb_kw_args): sl = EventListener() if len([x for x in self.slisteners if x.signum == signum]) == 0: signal.signal(signum, self.signal) sl.signum = signum sl.cb_func = signal_cb sl.cb_params = cb_params sl.cb_kw_args = cb_kw_args self.slisteners.append(sl) return sl def unregSignal(self, sl): self.slisteners.remove(sl) if len([x for x in self.slisteners if x.signum == sl.signum]) == 0: signal.signal(sl.signum, signal.SIG_DFL) sl.cleanup() def dispatchSignals(self): while len(self.signals_pending) > 0: signum = self.signals_pending.pop(0) for sl in [x for x in self.slisteners if x.signum == signum]: if sl not in self.slisteners: continue try: sl.cb_func(*sl.cb_params, **sl.cb_kw_args) except Exception as ex: if isinstance(ex, SystemExit): raise dump_exception('EventDispatcher2: unhandled exception when processing signal event') if self.endloop: return def dispatchThreadCallback(self, thread_cb, cb_params): try: thread_cb(*cb_params) except Exception as ex: if isinstance(ex, SystemExit): raise dump_exception('EventDispatcher2: unhandled exception when processing from-thread-call') #print('dispatchThreadCallback dispatched', thread_cb, cb_params) def callFromThread(self, thread_cb, *cb_params): self.elp.call_from_thread(self.dispatchThreadCallback, thread_cb, cb_params) #print('EventDispatcher2.callFromThread completed', str(self), thread_cb, cb_params) def loop(self, timeout = None, freq = None): if freq != None and self.bands[0][0] != freq: for fb in self.bands: if fb[0] == freq: self.bands.remove(fb) break else: fb = (freq, self.elp.addband(freq)) self.elp.useband(fb[1]) self.bands.insert(0, fb) self.endloop = False self.last_ts = MonoTime() if timeout != None: etime = self.last_ts.getOffsetCopy(timeout) while True: if len(self.signals_pending) > 0: self.dispatchSignals() if self.endloop: return if self.endloop: return self.dispatchTimers() if self.endloop: return if self.twasted * 2 > len(self.tlisteners): # Clean-up removed timers when their share becomes more than 50% self.tlisteners = [x for x in self.tlisteners if x.cb_func != None] heapify(self.tlisteners) self.twasted = 0 if (timeout != None and self.last_ts > etime) or self.endloop: self.endloop = False break self.elp.procrastinate() self.last_ts = MonoTime() def breakLoop(self): self.endloop = True
from twisted.internet import reactor from sippy.Time.MonoTime import MonoTime def test1(arguments, testnum, mtm): arguments['delay'] = mtm.offsetFromNow() print testnum, arguments['delay'] arguments['test'] = True reactor.crash() def test2(arguments, testnum, mtm): arguments['delay'] = mtm.offsetFromNow() print testnum, arguments['delay'] arguments['test'] = 'bar' reactor.crash() mt = MonoTime() arguments = {'test':False, 'delay':None} timeout_1 = TimeoutAbsMono(test1, mt, arguments, 'test1', mt) reactor.run() assert(arguments['test']) assert(arguments['delay'] < 0.1) mt1 = mt.getOffsetCopy(0.1) mt2 = mt.getOffsetCopy(0.2) arguments = {'test':False, 'delay':None} timeout_1 = TimeoutAbsMono(test1, mt1, arguments, 'test2', mt1) timeout_2 = TimeoutAbsMono(test2, mt2, arguments, 'test3', mt2) timeout_1.cancel() reactor.run() assert(arguments['test'] == 'bar') assert(arguments['delay'] < 0.1)
def disconnect(self, rtime=None): if rtime == None: rtime = MonoTime() self.equeue.append(CCEventDisconnect(rtime=rtime)) self.recvEvent(CCEventDisconnect(rtime=rtime))