Пример #1
0
 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()
Пример #2
0
 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()
Пример #3
0
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)
Пример #4
0
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')
Пример #5
0
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)
Пример #6
0
 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()
Пример #7
0
 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
Пример #8
0
 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),]
Пример #9
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)
Пример #10
0
 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
Пример #11
0
 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)
Пример #12
0
 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
Пример #13
0
 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)
Пример #14
0
 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
Пример #15
0
 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)
Пример #16
0
 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)
Пример #17
0
 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)
Пример #18
0
 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
Пример #19
0
 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))
Пример #20
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
Пример #21
0
    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)
Пример #22
0
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
Пример #23
0
    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)
Пример #24
0
 def disconnect(self, rtime=None):
     if rtime == None:
         rtime = MonoTime()
     self.equeue.append(CCEventDisconnect(rtime=rtime))
     self.recvEvent(CCEventDisconnect(rtime=rtime))