示例#1
0
    def __init__(self, scheduler, useEpoll=False):
        # We store tuples of (elapse-time, task)
        self._sleepers = []  # Sleeping items stored as a heap
        self._incoming = Queue()  # Threadsafe queue for new items

        self._scheduler = scheduler
        self._pinger = pox.lib.util.makePinger()
        self.epoll = EpollSelect() if useEpoll else None

        self._ready = False

        self._thread = Thread(target=self._threadProc)
        self._thread.daemon = True
        self._thread.start()
示例#2
0
    def __init__(self, scheduler, useEpoll=False, threaded=True):
        # We store tuples of (elapse-time, task)
        self._incoming = Queue()  # Threadsafe queue for new items

        self._scheduler = scheduler
        self._pinger = pox.lib.util.makePinger()
        self.epoll = EpollSelect() if useEpoll else None

        self._tasks = {}

        self._thread = None
        if threaded:
            self._thread = Thread(target=self._threadProc)
            self._thread.daemon = True
            self._thread.start()
            self._event = threading.Event()
示例#3
0
class EpollSelectTest(unittest.TestCase):
    def setUp(self):
        self.es = EpollSelect()
        self.server = ForkingTCPServer(("localhost", 0), TCPEcho)
        self.ip, self.port = self.server.server_address
        self.server.start()

    def tearDown(self):
        self.es.close()
        self.server.stop()

    def test_create(self):
        pass

    def test_read_one_socket(self):
        c = socket.create_connection((self.ip, self.port))
        ret = self.es.select([c], [], [c], 0.1)
        self.assertEqual(([], [], []), ret)
        # socket is ready to send?
        ret = self.es.select([c], [c], [c], 0.1)
        self.assertEqual(([], [c], []), ret)
        # send stuff
        c.send("Hallo\n")
        # now we have something to read, right?
        ret = self.es.select([c], [], [c], 0.5)
        self.assertEqual(([c], [], []), ret)

    def test_write_more_sockets(self):
        c1 = socket.create_connection((self.ip, self.port))
        c2 = socket.create_connection((self.ip, self.port))
        c3 = socket.create_connection((self.ip, self.port))
        # note don't throw away the socket -- else it will be garbage collected
        raw = c3.fileno()
        seq = [[c1], [c2], [c1, c2], [c1, c2, raw], [c1], [raw]]

        check = lambda a, b: self.assertEqual(sort_fdlists(*a), sort_fdlists(*b
                                                                             ))

        #just the writes
        for sockets in seq:
            check(([], sockets, []),
                  self.es.select(sockets, sockets, sockets, 0))

        # writes and reads in different order
        for sockets in seq:
            check(([], [], []), self.es.select(sockets, [], sockets, 0))
            check(([], sockets, []),
                  self.es.select(sockets, sockets, sockets, 0))
示例#4
0
文件: recoco.py 项目: voidcc/PCTRL
  def __init__ (self, scheduler, useEpoll=False):
    # We store tuples of (elapse-time, task)
    self._sleepers = [] # Sleeping items stored as a heap
    self._incoming = Queue() # Threadsafe queue for new items

    self._scheduler = scheduler
    self._pinger = pox.lib.util.makePinger()
    self.epoll = EpollSelect() if useEpoll else None

    self._ready = False

    self._thread = Thread(target = self._threadProc)
    self._thread.daemon = True
    self._thread.start()
  def __init__ (self, scheduler, useEpoll=False, threaded=True):
    # We store tuples of (elapse-time, task)
    self._incoming = Queue() # Threadsafe queue for new items

    self._scheduler = scheduler
    self._pinger = pox.lib.util.makePinger()
    self.epoll = EpollSelect() if useEpoll else None

    self._tasks = {}

    self._thread = None
    if threaded:
      self._thread = Thread(target = self._threadProc)
      self._thread.daemon = True
      self._thread.start()
      self._event = threading.Event()
class EpollSelectTest(unittest.TestCase):
  def setUp(self):
    self.es = EpollSelect()
    self.server = ForkingTCPServer(("localhost", 0), TCPEcho)
    self.ip, self.port = self.server.server_address
    self.server.start()

  def tearDown(self):
    self.es.close()
    self.server.stop()

  def test_create(self):
    pass

  def test_read_one_socket(self):
    c = socket.create_connection( (self.ip, self.port))
    ret  = self.es.select([c], [], [c], 0.1)
    self.assertEqual(([],[],[]), ret)
    # socket is ready to send?
    ret  = self.es.select([c], [c], [c], 0.1)
    self.assertEqual(([],[c],[]), ret)
    # send stuff
    c.send("Hallo\n")
    # now we have something to read, right?
    ret  = self.es.select([c], [], [c], 0.5)
    self.assertEqual(([c],[],[]), ret)

  def test_write_more_sockets(self):
    c1 = socket.create_connection( (self.ip, self.port))
    c2 = socket.create_connection( (self.ip, self.port))
    c3 = socket.create_connection( (self.ip, self.port))
    # note don't throw away the socket -- else it will be garbage collected
    raw = c3.fileno()
    seq = [ [c1], [c2], [c1,c2], [c1,c2, raw], [c1], [raw]]

    check = lambda a,b: self.assertEqual(sort_fdlists(*a), sort_fdlists(*b))

    #just the writes
    for sockets in seq:
     check(([],sockets,[]),self.es.select(sockets, sockets, sockets, 0))

    # writes and reads in different order
    for sockets in seq:
      check( ([],[],[]), self.es.select(sockets, [], sockets, 0))
      check( ([],sockets,[]), self.es.select(sockets, sockets, sockets, 0))
class SelectHub (object):
  """
  This class is a single select() loop that handles all Select() requests for
  a scheduler as well as timed wakes (i.e., Sleep()).
  """
  def __init__ (self, scheduler, useEpoll=False, threaded=True):
    # We store tuples of (elapse-time, task)
    self._incoming = Queue() # Threadsafe queue for new items

    self._scheduler = scheduler
    self._pinger = pox.lib.util.makePinger()
    self.epoll = EpollSelect() if useEpoll else None

    self._tasks = {}

    self._thread = None
    if threaded:
      self._thread = Thread(target = self._threadProc)
      self._thread.daemon = True
      self._thread.start()
      self._event = threading.Event()

  def idle (self):
    """
    Called by the scheduler when the scheduler has nothing to do

    This should block until there's IO or until break_idle().
    (Or at least should block up to CYCLE_MAXIMUM)
    """
    if self._thread:
      # We're running select on another thread

      self._event.wait(CYCLE_MAXIMUM) # Wait for a while
      self._event.clear()
    else:
      # We're running select on the same thread as scheduler
      self._select(self._tasks, {})

  def break_idle (self):
    """
    Break a call to idle()
    """
    if self._thread:
      self._event.set()
    else:
      self._cycle()

  def _threadProc (self):
    tasks = self._tasks
    rets = {}
    _select = self._select
    _scheduler = self._scheduler

    while not _scheduler._hasQuit:
      _select(tasks, rets)

  def _select (self, tasks, rets):
    #print("SelectHub cycle")

    #NOTE: Everything you select on eventually boils down to file descriptors,
    #      which are unique, obviously.  It might be possible to leverage this
    #      to reduce hashing cost (i.e. by picking a really good hashing
    #      function), though this is complicated by wrappers, etc...
    rl = {}
    wl = {}
    xl = {}

    timeout = None
    timeoutTask = None

    now = time.time()

    expired = None

    #TODO: Fix this.  It's pretty expensive.  There had been some code which
    #      priority heaped this, but I don't think a fully working version
    #      ever quite made it.
    for t,trl,twl,txl,tto in tasks.itervalues():
      if tto != None:
        if tto <= now:
          # Already expired
          if expired is None: expired = []
          expired.append(t)
          if tto-now > 0.1: print("preexpired",tto,now,tto-now)
          continue
        tt = tto - now
        if tt < timeout or timeout is None:
          timeout = tt
          timeoutTask = t

      if trl:
        for i in trl: rl[i] = t
      if twl:
        for i in twl: wl[i] = t
      if txl:
        for i in txl: xl[i] = t

    if expired:
      for t in expired:
        del tasks[t]
        self._return(t, ([],[],[]))

    if timeout is None: timeout = CYCLE_MAXIMUM
    if self.epoll:
      ro, wo, xo = self.epoll.select( rl.keys() + [self._pinger],
                                wl.keys(),
                                xl.keys(), timeout )
    else:
      ro, wo, xo = select.select( rl.keys() + [self._pinger],
                                wl.keys(),
                                xl.keys(), timeout )

    if len(ro) == 0 and len(wo) == 0 and len(xo) == 0 and timeoutTask != None:
      # IO is idle - dispatch timers / release timeouts
      del tasks[timeoutTask]
      self._return(timeoutTask, ([],[],[]))
    else:
      # We have IO events
      if self._pinger in ro:
        self._pinger.pongAll()
        while not self._incoming.empty():
          stuff = self._incoming.get(True)
          task = stuff[0]
          assert task not in tasks
          tasks[task] = stuff
          self._incoming.task_done()
        if len(ro) == 1 and len(wo) == 0 and len(xo) == 0:
          # Just recycle
          return
        ro.remove(self._pinger)

      # At least one thread is going to be resumed
      for i in ro:
        task = rl[i]
        if task not in rets: rets[task] = ([],[],[])
        rets[task][0].append(i)
      for i in wo:
        task = wl[i]
        if task not in rets: rets[task] = ([],[],[])
        rets[task][1].append(i)
      for i in xo:
        task = xl[i]
        if task not in rets: rets[task] = ([],[],[])
        rets[task][2].append(i)

      for t,v in rets.iteritems():
        del tasks[t]
        self._return(t, v)
      rets.clear()

  def registerSelect (self, task, rlist = None, wlist = None, xlist = None,
                      timeout = None, timeIsAbsolute = False):
    if not timeIsAbsolute:
      if timeout != None:
        timeout += time.time()

    self._incoming.put((task, rlist, wlist, xlist, timeout))
    self._cycle()

  def _cycle (self):
    """
    Cycle the wait thread so that new timers or FDs can be picked up
    """
    self._pinger.ping()

  def registerTimer (self, task, timeToWake, timeIsAbsolute = False):
    """
    Register a task to be wakened up interval units in the future.
    It means timeToWake seconds in the future if absoluteTime is False.
    """
    return self.registerSelect(task, None, None, None, timeToWake,
                               timeIsAbsolute)

  def _return (self, sleepingTask, returnVal):
    #print("reschedule", sleepingTask)
    sleepingTask.rv = returnVal
    self._scheduler.fast_schedule(sleepingTask)
示例#8
0
class SelectHub(object):
    """
  This class is a single select() loop that handles all Select() requests for
  a scheduler as well as timed wakes (i.e., Sleep()).
  """
    def __init__(self, scheduler, useEpoll=False):
        # We store tuples of (elapse-time, task)
        self._sleepers = []  # Sleeping items stored as a heap
        self._incoming = Queue()  # Threadsafe queue for new items

        self._scheduler = scheduler
        self._pinger = pox.lib.util.makePinger()
        self.epoll = EpollSelect() if useEpoll else None

        self._ready = False

        self._thread = Thread(target=self._threadProc)
        self._thread.daemon = True
        self._thread.start()

        # Ugly busy wait for initialization
        #while self._ready == False:

    def _threadProc(self):
        tasks = {}
        timeouts = []
        rets = {}

        while self._scheduler._hasQuit == False:
            #print("SelectHub cycle")

            if len(timeouts) == 0:
                timeout = None
            else:
                timeout = self._sleepers[0][0] - time.time()
                if timeout < 0: timeout = 0

            #NOTE: Everything you select on eventually boils down to file descriptors,
            #      which are unique, obviously.  It might be possible to leverage this
            #      to reduce hashing cost (i.e. by picking a really good hashing
            #      function), though this is complicated by wrappers, etc...
            rl = {}
            wl = {}
            xl = {}

            timeout = None
            timeoutTask = None

            now = time.time()

            expired = None

            for t, trl, twl, txl, tto in tasks.itervalues():
                if tto != None:
                    if tto <= now:
                        # Already expired
                        if expired is None: expired = []
                        expired.append(t)
                        if tto - now > 0.1:
                            print("preexpired", tto, now, tto - now)
                        continue
                    tt = tto - now
                    if tt < timeout or timeout is None:
                        timeout = tt
                        timeoutTask = t

                if trl:
                    for i in trl:
                        rl[i] = t
                if twl:
                    for i in twl:
                        wl[i] = t
                if txl:
                    for i in txl:
                        xl[i] = t

            if expired:
                for t in expired:
                    del tasks[t]
                    self._return(t, ([], [], []))

            if timeout is None: timeout = CYCLE_MAXIMUM
            if self.epoll:
                ro, wo, xo = self.epoll.select(rl.keys() + [self._pinger],
                                               wl.keys(), xl.keys(), timeout)
            else:
                ro, wo, xo = select.select(rl.keys() + [self._pinger],
                                           wl.keys(), xl.keys(), timeout)

            if len(ro) == 0 and len(wo) == 0 and len(
                    xo) == 0 and timeoutTask != None:
                # IO is idle - dispatch timers / release timeouts
                del tasks[timeoutTask]
                self._return(timeoutTask, ([], [], []))
            else:
                # We have IO events
                if self._pinger in ro:
                    self._pinger.pongAll()
                    while not self._incoming.empty():
                        stuff = self._incoming.get(True)
                        task = stuff[0]
                        assert task not in tasks
                        tasks[task] = stuff
                        self._incoming.task_done()
                    if len(ro) == 1 and len(wo) == 0 and len(xo) == 0:
                        # Just recycle
                        continue
                    ro.remove(self._pinger)

                # At least one thread is going to be resumed
                for i in ro:
                    task = rl[i]
                    if task not in rets: rets[task] = ([], [], [])
                    rets[task][0].append(i)
                for i in wo:
                    task = wl[i]
                    if task not in rets: rets[task] = ([], [], [])
                    rets[task][1].append(i)
                for i in xo:
                    task = xl[i]
                    if task not in rets: rets[task] = ([], [], [])
                    rets[task][2].append(i)

                for t, v in rets.iteritems():
                    del tasks[t]
                    self._return(t, v)
                rets.clear()

    def registerSelect(self,
                       task,
                       rlist=None,
                       wlist=None,
                       xlist=None,
                       timeout=None,
                       timeIsAbsolute=False):
        if not timeIsAbsolute:
            if timeout != None:
                timeout += time.time()

        self._incoming.put((task, rlist, wlist, xlist, timeout))
        self._cycle()

    def _cycle(self):
        """
    Cycle the wait thread so that new timers or FDs can be picked up
    """
        self._pinger.ping()

    def registerTimer(self, task, timeToWake, timeIsAbsolute=False):
        """
    Register a task to be wakened up interval units in the future.
    It means timeToWake seconds in the future if absoluteTime is False.
    """
        return self.registerSelect(task, None, None, None, timeToWake,
                                   timeIsAbsolute)

    def _return(self, sleepingTask, returnVal):
        #print("reschedule", sleepingTask)
        sleepingTask.rv = returnVal
        self._scheduler.fast_schedule(sleepingTask)
 def setUp(self):
   self.es = EpollSelect()
   self.server = ForkingTCPServer(("localhost", 0), TCPEcho)
   self.ip, self.port = self.server.server_address
   self.server.start()
示例#10
0
 def setUp(self):
     self.es = EpollSelect()
     self.server = ForkingTCPServer(("localhost", 0), TCPEcho)
     self.ip, self.port = self.server.server_address
     self.server.start()