[Python-checkins] python/dist/src/Lib asyncore.py,1.33,1.34

gvanrossum@users.sourceforge.net gvanrossum@users.sourceforge.net
Wed, 11 Sep 2002 21:57:32 -0700


Update of /cvsroot/python/python/dist/src/Lib
In directory usw-pr-cvs1:/tmp/cvs-serv4385

Modified Files:
	asyncore.py 
Log Message:
I don't think it's safe to use map.iteritems() in the various poll
routines.  I got some errors "dictionary changed size during
iteration" when running ZEO tests on machine while doing heavy
forground work in another window, and thinking about it, I believe
that it should be okay if readable() or writable() modifies the map.

I also finally made all the spacing conform to the Python style guide:
no space between a function/method name and the following left
parenthesis (fixed lots of occurrences), spaces around assignment
operators (fixed a few, always of the form "map=..."), and a blank
line between the class statement and the first method definition (a
few).


Index: asyncore.py
===================================================================
RCS file: /cvsroot/python/python/dist/src/Lib/asyncore.py,v
retrieving revision 1.33
retrieving revision 1.34
diff -C2 -d -r1.33 -r1.34
*** asyncore.py	8 Sep 2002 00:14:54 -0000	1.33
--- asyncore.py	12 Sep 2002 04:57:29 -0000	1.34
***************
*** 91,100 ****
          obj.handle_error()
  
! def poll (timeout=0.0, map=None):
      if map is None:
          map = socket_map
      if map:
          r = []; w = []; e = []
!         for fd, obj in map.iteritems():
              if obj.readable():
                  r.append(fd)
--- 91,100 ----
          obj.handle_error()
  
! def poll(timeout=0.0, map=None):
      if map is None:
          map = socket_map
      if map:
          r = []; w = []; e = []
!         for fd, obj in map.items():
              if obj.readable():
                  r.append(fd)
***************
*** 119,126 ****
              write(obj)
  
! def poll2 (timeout=0.0, map=None):
      import poll
      if map is None:
!         map=socket_map
      if timeout is not None:
          # timeout is in milliseconds
--- 119,126 ----
              write(obj)
  
! def poll2(timeout=0.0, map=None):
      import poll
      if map is None:
!         map = socket_map
      if timeout is not None:
          # timeout is in milliseconds
***************
*** 128,132 ****
      if map:
          l = []
!         for fd, obj in map.iteritems():
              flags = 0
              if obj.readable():
--- 128,132 ----
      if map:
          l = []
!         for fd, obj in map.items():
              flags = 0
              if obj.readable():
***************
*** 135,140 ****
                  flags = flags | poll.POLLOUT
              if flags:
!                 l.append ((fd, flags))
!         r = poll.poll (l, timeout)
          for fd, flags in r:
              obj = map.get(fd)
--- 135,140 ----
                  flags = flags | poll.POLLOUT
              if flags:
!                 l.append((fd, flags))
!         r = poll.poll(l, timeout)
          for fd, flags in r:
              obj = map.get(fd)
***************
*** 143,150 ****
              readwrite(obj, flags)
  
! def poll3 (timeout=0.0, map=None):
      # Use the poll() support added to the select module in Python 2.0
      if map is None:
!         map=socket_map
      if timeout is not None:
          # timeout is in milliseconds
--- 143,150 ----
              readwrite(obj, flags)
  
! def poll3(timeout=0.0, map=None):
      # Use the poll() support added to the select module in Python 2.0
      if map is None:
!         map = socket_map
      if timeout is not None:
          # timeout is in milliseconds
***************
*** 152,156 ****
      pollster = select.poll()
      if map:
!         for fd, obj in map.iteritems():
              flags = 0
              if obj.readable():
--- 152,156 ----
      pollster = select.poll()
      if map:
!         for fd, obj in map.items():
              flags = 0
              if obj.readable():
***************
*** 161,165 ****
                  pollster.register(fd, flags)
          try:
!             r = pollster.poll (timeout)
          except select.error, err:
              if err[0] != EINTR:
--- 161,165 ----
                  pollster.register(fd, flags)
          try:
!             r = pollster.poll(timeout)
          except select.error, err:
              if err[0] != EINTR:
***************
*** 172,181 ****
              readwrite(obj, flags)
  
! def loop (timeout=30.0, use_poll=0, map=None):
      if map is None:
          map = socket_map
  
      if use_poll:
!         if hasattr (select, 'poll'):
              poll_fun = poll3
          else:
--- 172,181 ----
              readwrite(obj, flags)
  
! def loop(timeout=30.0, use_poll=0, map=None):
      if map is None:
          map = socket_map
  
      if use_poll:
!         if hasattr(select, 'poll'):
              poll_fun = poll3
          else:
***************
*** 185,191 ****
  
      while map:
!         poll_fun (timeout, map)
  
  class dispatcher:
      debug = 0
      connected = 0
--- 185,192 ----
  
      while map:
!         poll_fun(timeout, map)
  
  class dispatcher:
+ 
      debug = 0
      connected = 0
***************
*** 194,202 ****
      addr = None
  
!     def __init__ (self, sock=None, map=None):
          if sock:
!             self.set_socket (sock, map)
              # I think it should inherit this anyway
!             self.socket.setblocking (0)
              self.connected = 1
              # XXX Does the constructor require that the socket passed
--- 195,203 ----
      addr = None
  
!     def __init__(self, sock=None, map=None):
          if sock:
!             self.set_socket(sock, map)
              # I think it should inherit this anyway
!             self.socket.setblocking(0)
              self.connected = 1
              # XXX Does the constructor require that the socket passed
***************
*** 210,260 ****
              self.socket = None
  
!     def __repr__ (self):
          status = [self.__class__.__module__+"."+self.__class__.__name__]
          if self.accepting and self.addr:
!             status.append ('listening')
          elif self.connected:
!             status.append ('connected')
          if self.addr is not None:
              try:
!                 status.append ('%s:%d' % self.addr)
              except TypeError:
!                 status.append (repr(self.addr))
!         return '<%s at %#x>' % (' '.join (status), id (self))
  
!     def add_channel (self, map=None):
!         #self.log_info ('adding channel %s' % self)
          if map is None:
!             map=socket_map
          map [self._fileno] = self
  
!     def del_channel (self, map=None):
          fd = self._fileno
          if map is None:
!             map=socket_map
!         if map.has_key (fd):
!             #self.log_info ('closing channel %d:%s' % (fd, self))
              del map [fd]
  
!     def create_socket (self, family, type):
          self.family_and_type = family, type
!         self.socket = socket.socket (family, type)
          self.socket.setblocking(0)
          self._fileno = self.socket.fileno()
          self.add_channel()
  
!     def set_socket (self, sock, map=None):
          self.socket = sock
  ##        self.__dict__['socket'] = sock
          self._fileno = sock.fileno()
!         self.add_channel (map)
  
!     def set_reuse_addr (self):
          # try to re-use a server port if possible
          try:
!             self.socket.setsockopt (
                  socket.SOL_SOCKET, socket.SO_REUSEADDR,
!                 self.socket.getsockopt (socket.SOL_SOCKET,
!                                         socket.SO_REUSEADDR) | 1
                  )
          except socket.error:
--- 211,261 ----
              self.socket = None
  
!     def __repr__(self):
          status = [self.__class__.__module__+"."+self.__class__.__name__]
          if self.accepting and self.addr:
!             status.append('listening')
          elif self.connected:
!             status.append('connected')
          if self.addr is not None:
              try:
!                 status.append('%s:%d' % self.addr)
              except TypeError:
!                 status.append(repr(self.addr))
!         return '<%s at %#x>' % (' '.join(status), id(self))
  
!     def add_channel(self, map=None):
!         #self.log_info('adding channel %s' % self)
          if map is None:
!             map = socket_map
          map [self._fileno] = self
  
!     def del_channel(self, map=None):
          fd = self._fileno
          if map is None:
!             map = socket_map
!         if map.has_key(fd):
!             #self.log_info('closing channel %d:%s' % (fd, self))
              del map [fd]
  
!     def create_socket(self, family, type):
          self.family_and_type = family, type
!         self.socket = socket.socket(family, type)
          self.socket.setblocking(0)
          self._fileno = self.socket.fileno()
          self.add_channel()
  
!     def set_socket(self, sock, map=None):
          self.socket = sock
  ##        self.__dict__['socket'] = sock
          self._fileno = sock.fileno()
!         self.add_channel(map)
  
!     def set_reuse_addr(self):
          # try to re-use a server port if possible
          try:
!             self.socket.setsockopt(
                  socket.SOL_SOCKET, socket.SO_REUSEADDR,
!                 self.socket.getsockopt(socket.SOL_SOCKET,
!                                        socket.SO_REUSEADDR) | 1
                  )
          except socket.error:
***************
*** 267,271 ****
      # ==================================================
  
!     def readable (self):
          return True
  
--- 268,272 ----
      # ==================================================
  
!     def readable(self):
          return True
  
***************
*** 273,280 ****
          # The macintosh will select a listening socket for
          # write if you let it.  What might this mean?
!         def writable (self):
              return not self.accepting
      else:
!         def writable (self):
              return True
  
--- 274,281 ----
          # The macintosh will select a listening socket for
          # write if you let it.  What might this mean?
!         def writable(self):
              return not self.accepting
      else:
!         def writable(self):
              return True
  
***************
*** 283,297 ****
      # ==================================================
  
!     def listen (self, num):
          self.accepting = 1
          if os.name == 'nt' and num > 5:
              num = 1
!         return self.socket.listen (num)
  
!     def bind (self, addr):
          self.addr = addr
!         return self.socket.bind (addr)
  
!     def connect (self, address):
          self.connected = 0
          err = self.socket.connect_ex(address)
--- 284,298 ----
      # ==================================================
  
!     def listen(self, num):
          self.accepting = 1
          if os.name == 'nt' and num > 5:
              num = 1
!         return self.socket.listen(num)
  
!     def bind(self, addr):
          self.addr = addr
!         return self.socket.bind(addr)
  
!     def connect(self, address):
          self.connected = 0
          err = self.socket.connect_ex(address)
***************
*** 305,309 ****
              raise socket.error, err
  
!     def accept (self):
          # XXX can return either an address pair or None
          try:
--- 306,310 ----
              raise socket.error, err
  
!     def accept(self):
          # XXX can return either an address pair or None
          try:
***************
*** 316,322 ****
                  raise socket.error, why
  
!     def send (self, data):
          try:
!             result = self.socket.send (data)
              return result
          except socket.error, why:
--- 317,323 ----
                  raise socket.error, why
  
!     def send(self, data):
          try:
!             result = self.socket.send(data)
              return result
          except socket.error, why:
***************
*** 327,333 ****
              return 0
  
!     def recv (self, buffer_size):
          try:
!             data = self.socket.recv (buffer_size)
              if not data:
                  # a closed connection is indicated by signaling
--- 328,334 ----
              return 0
  
!     def recv(self, buffer_size):
          try:
!             data = self.socket.recv(buffer_size)
              if not data:
                  # a closed connection is indicated by signaling
***************
*** 345,349 ****
                  raise socket.error, why
  
!     def close (self):
          self.del_channel()
          self.socket.close()
--- 346,350 ----
                  raise socket.error, why
  
!     def close(self):
          self.del_channel()
          self.socket.close()
***************
*** 351,356 ****
      # cheap inheritance, used to pass all other attribute
      # references to the underlying socket object.
!     def __getattr__ (self, attr):
!         return getattr (self.socket, attr)
  
      # log and log_info maybe overriden to provide more sophisitcated
--- 352,357 ----
      # cheap inheritance, used to pass all other attribute
      # references to the underlying socket object.
!     def __getattr__(self, attr):
!         return getattr(self.socket, attr)
  
      # log and log_info maybe overriden to provide more sophisitcated
***************
*** 358,369 ****
      # and 'log_info' is for informational, warning and error logging.
  
!     def log (self, message):
!         sys.stderr.write ('log: %s\n' % str(message))
  
!     def log_info (self, message, type='info'):
          if __debug__ or type != 'info':
              print '%s: %s' % (type, message)
  
!     def handle_read_event (self):
          if self.accepting:
              # for an accepting socket, getting a read implies
--- 359,370 ----
      # and 'log_info' is for informational, warning and error logging.
  
!     def log(self, message):
!         sys.stderr.write('log: %s\n' % str(message))
  
!     def log_info(self, message, type='info'):
          if __debug__ or type != 'info':
              print '%s: %s' % (type, message)
  
!     def handle_read_event(self):
          if self.accepting:
              # for an accepting socket, getting a read implies
***************
*** 379,383 ****
              self.handle_read()
  
!     def handle_write_event (self):
          # getting a write implies that we are connected
          if not self.connected:
--- 380,384 ----
              self.handle_read()
  
!     def handle_write_event(self):
          # getting a write implies that we are connected
          if not self.connected:
***************
*** 386,402 ****
          self.handle_write()
  
!     def handle_expt_event (self):
          self.handle_expt()
  
!     def handle_error (self):
          nil, t, v, tbinfo = compact_traceback()
  
          # sometimes a user repr method will crash.
          try:
!             self_repr = repr (self)
          except:
!             self_repr = '<__repr__ (self) failed for object at %0x>' % id(self)
  
!         self.log_info (
              'uncaptured python exception, closing channel %s (%s:%s %s)' % (
                  self_repr,
--- 387,403 ----
          self.handle_write()
  
!     def handle_expt_event(self):
          self.handle_expt()
  
!     def handle_error(self):
          nil, t, v, tbinfo = compact_traceback()
  
          # sometimes a user repr method will crash.
          try:
!             self_repr = repr(self)
          except:
!             self_repr = '<__repr__(self) failed for object at %0x>' % id(self)
  
!         self.log_info(
              'uncaptured python exception, closing channel %s (%s:%s %s)' % (
                  self_repr,
***************
*** 409,429 ****
          self.close()
  
!     def handle_expt (self):
!         self.log_info ('unhandled exception', 'warning')
  
!     def handle_read (self):
!         self.log_info ('unhandled read event', 'warning')
  
!     def handle_write (self):
!         self.log_info ('unhandled write event', 'warning')
  
!     def handle_connect (self):
!         self.log_info ('unhandled connect event', 'warning')
  
!     def handle_accept (self):
!         self.log_info ('unhandled accept event', 'warning')
  
!     def handle_close (self):
!         self.log_info ('unhandled close event', 'warning')
          self.close()
  
--- 410,430 ----
          self.close()
  
!     def handle_expt(self):
!         self.log_info('unhandled exception', 'warning')
  
!     def handle_read(self):
!         self.log_info('unhandled read event', 'warning')
  
!     def handle_write(self):
!         self.log_info('unhandled write event', 'warning')
  
!     def handle_connect(self):
!         self.log_info('unhandled connect event', 'warning')
  
!     def handle_accept(self):
!         self.log_info('unhandled accept event', 'warning')
  
!     def handle_close(self):
!         self.log_info('unhandled close event', 'warning')
          self.close()
  
***************
*** 433,455 ****
  # ---------------------------------------------------------------------------
  
! class dispatcher_with_send (dispatcher):
!     def __init__ (self, sock=None):
!         dispatcher.__init__ (self, sock)
          self.out_buffer = ''
  
!     def initiate_send (self):
          num_sent = 0
!         num_sent = dispatcher.send (self, self.out_buffer[:512])
          self.out_buffer = self.out_buffer[num_sent:]
  
!     def handle_write (self):
          self.initiate_send()
  
!     def writable (self):
          return (not self.connected) or len(self.out_buffer)
  
!     def send (self, data):
          if self.debug:
!             self.log_info ('sending %s' % repr(data))
          self.out_buffer = self.out_buffer + data
          self.initiate_send()
--- 434,457 ----
  # ---------------------------------------------------------------------------
  
! class dispatcher_with_send(dispatcher):
! 
!     def __init__(self, sock=None):
!         dispatcher.__init__(self, sock)
          self.out_buffer = ''
  
!     def initiate_send(self):
          num_sent = 0
!         num_sent = dispatcher.send(self, self.out_buffer[:512])
          self.out_buffer = self.out_buffer[num_sent:]
  
!     def handle_write(self):
          self.initiate_send()
  
!     def writable(self):
          return (not self.connected) or len(self.out_buffer)
  
!     def send(self, data):
          if self.debug:
!             self.log_info('sending %s' % repr(data))
          self.out_buffer = self.out_buffer + data
          self.initiate_send()
***************
*** 459,467 ****
  # ---------------------------------------------------------------------------
  
! def compact_traceback ():
      t,v,tb = sys.exc_info()
      tbinfo = []
      while 1:
!         tbinfo.append ((
              tb.tb_frame.f_code.co_filename,
              tb.tb_frame.f_code.co_name,
--- 461,469 ----
  # ---------------------------------------------------------------------------
  
! def compact_traceback():
      t,v,tb = sys.exc_info()
      tbinfo = []
      while 1:
!         tbinfo.append((
              tb.tb_frame.f_code.co_filename,
              tb.tb_frame.f_code.co_name,
***************
*** 479,485 ****
      return (file, function, line), t, v, info
  
! def close_all (map=None):
      if map is None:
!         map=socket_map
      for x in map.values():
          x.socket.close()
--- 481,487 ----
      return (file, function, line), t, v, info
  
! def close_all(map=None):
      if map is None:
!         map = socket_map
      for x in map.values():
          x.socket.close()
***************
*** 505,515 ****
          # here we override just enough to make a file
          # look like a socket for the purposes of asyncore.
!         def __init__ (self, fd):
              self.fd = fd
  
!         def recv (self, *args):
              return os.read(self.fd, *args)
  
!         def send (self, *args):
              return os.write(self.fd, *args)
  
--- 507,518 ----
          # here we override just enough to make a file
          # look like a socket for the purposes of asyncore.
! 
!         def __init__(self, fd):
              self.fd = fd
  
!         def recv(self, *args):
              return os.read(self.fd, *args)
  
!         def send(self, *args):
              return os.write(self.fd, *args)
  
***************
*** 517,538 ****
          write = send
  
!         def close (self):
!             return os.close (self.fd)
  
!         def fileno (self):
              return self.fd
  
!     class file_dispatcher (dispatcher):
!         def __init__ (self, fd):
!             dispatcher.__init__ (self)
              self.connected = 1
              # set it to non-blocking mode
!             flags = fcntl.fcntl (fd, fcntl.F_GETFL, 0)
              flags = flags | os.O_NONBLOCK
!             fcntl.fcntl (fd, fcntl.F_SETFL, flags)
!             self.set_file (fd)
  
!         def set_file (self, fd):
              self._fileno = fd
!             self.socket = file_wrapper (fd)
              self.add_channel()
--- 520,542 ----
          write = send
  
!         def close(self):
!             return os.close(self.fd)
  
!         def fileno(self):
              return self.fd
  
!     class file_dispatcher(dispatcher):
! 
!         def __init__(self, fd):
!             dispatcher.__init__(self)
              self.connected = 1
              # set it to non-blocking mode
!             flags = fcntl.fcntl(fd, fcntl.F_GETFL, 0)
              flags = flags | os.O_NONBLOCK
!             fcntl.fcntl(fd, fcntl.F_SETFL, flags)
!             self.set_file(fd)
  
!         def set_file(self, fd):
              self._fileno = fd
!             self.socket = file_wrapper(fd)
              self.add_channel()