[Python-checkins] python/nondist/sandbox/asyncore asyncore.py, 1.1, 1.2 asynchat.py, 1.1, 1.2

akuchling at users.sourceforge.net akuchling at users.sourceforge.net
Sun Mar 21 14:15:05 EST 2004


Update of /cvsroot/python/python/nondist/sandbox/asyncore
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv2630

Modified Files:
	asyncore.py asynchat.py 
Log Message:
Add patches from patch #909005

Index: asyncore.py
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/asyncore/asyncore.py,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** asyncore.py	21 Mar 2004 19:14:19 -0000	1.1
--- asyncore.py	21 Mar 2004 19:15:02 -0000	1.2
***************
*** 51,63 ****
  import socket
  import sys
- import time
  
  import os
  from errno import EALREADY, EINPROGRESS, EWOULDBLOCK, ECONNRESET, \
!      ENOTCONN, ESHUTDOWN, EINTR, EISCONN
  
! try:
!     socket_map
! except NameError:
      socket_map = {}
  
--- 51,61 ----
  import socket
  import sys
  
  import os
  from errno import EALREADY, EINPROGRESS, EWOULDBLOCK, ECONNRESET, \
!      ENOTCONN, ESHUTDOWN, EINTR, EISCONN, EBADF, \
!      errorcode
  
! if not 'socket_map' in dir():
      socket_map = {}
  
***************
*** 81,90 ****
          obj.handle_error()
  
  def readwrite(obj, flags):
      try:
!         if flags & select.POLLIN:
              obj.handle_read_event()
          if flags & select.POLLOUT:
              obj.handle_write_event()
      except ExitNow:
          raise
--- 79,98 ----
          obj.handle_error()
  
+ def expt(obj):
+     try:
+         obj.handle_expt_event()
+     except ExitNow:
+         raise
+     except:
+         obj.handle_error()
+ 
  def readwrite(obj, flags):
      try:
!         if flags & (select.POLLIN | select.POLLPRI):
              obj.handle_read_event()
          if flags & select.POLLOUT:
              obj.handle_write_event()
+         if flags & (select.POLLERR | select.POLLHUP | select.POLLNVAL):
+             obj.handle_expt_event()
      except ExitNow:
          raise
***************
*** 96,117 ****
          map = socket_map
      if map:
          r = []; w = []; e = []
          for fd, obj in map.items():
!             if obj.readable():
                  r.append(fd)
!             if obj.writable():
                  w.append(fd)
!         if [] == r == w == e:
!             time.sleep(timeout)
!         else:
!             try:
!                 r, w, e = select.select(r, w, e, timeout)
!             except select.error, err:
!                 if err[0] != EINTR:
!                     raise
!                 else:
!                     return
  
!         for fd in r:
              obj = map.get(fd)
              if obj is None:
--- 104,138 ----
          map = socket_map
      if map:
+         pr = []; pw = []
          r = []; w = []; e = []
          for fd, obj in map.items():
!             e.append(fd)
!             if obj.pending_read():
!                 pr.append(fd)
!                 timeout = 0.0
!             elif obj._readable():
                  r.append(fd)
!             if obj.pending_write():
!                 pw.append(fd)
!                 timeout = 0.0
!             elif obj._writable():
                  w.append(fd)
!         try:
!             #print '>', r, w, e
!             r, w, e = select.select(r, w, e, timeout)
!             #print '<', r, w, e
!         except select.error, err:
!             if err[0] != EINTR:
!                 raise
!             else:
!                 return
  
!         for fd in e:
!             obj = map.get(fd)
!             if obj is None:
!                 continue
!             expt(obj)
! 
!         for fd in pr + r:
              obj = map.get(fd)
              if obj is None:
***************
*** 119,123 ****
              read(obj)
  
!         for fd in w:
              obj = map.get(fd)
              if obj is None:
--- 140,144 ----
              read(obj)
  
!         for fd in pw + w:
              obj = map.get(fd)
              if obj is None:
***************
*** 134,145 ****
      pollster = select.poll()
      if map:
          for fd, obj in map.items():
!             flags = 0
!             if obj.readable():
!                 flags = select.POLLIN
!             if obj.writable():
                  flags = flags | select.POLLOUT
!             if flags:
!                 pollster.register(fd, flags)
          try:
              r = pollster.poll(timeout)
--- 155,172 ----
      pollster = select.poll()
      if map:
+         pr = []
          for fd, obj in map.items():
!             flags = select.POLLERR | select.POLLHUP | select.POLLNVAL
!             if obj.pending_read():
!                 pr.append((fd, select.POLLIN))
!                 timeout = 0.0
!             elif obj._readable():
!                 flags = select.POLLIN | select.POLLPRI
!             if obj.pending_write():
!                 pr.append((fd, select.POLLOUT))
!                 timeout = 0.0
!             elif obj._writable():
                  flags = flags | select.POLLOUT
!             pollster.register(fd, flags)
          try:
              r = pollster.poll(timeout)
***************
*** 147,152 ****
              if err[0] != EINTR:
                  raise
!             r = []
!         for fd, flags in r:
              obj = map.get(fd)
              if obj is None:
--- 174,181 ----
              if err[0] != EINTR:
                  raise
!             else:
!                 return
! 
!         for fd, flags in pr + r:
              obj = map.get(fd)
              if obj is None:
***************
*** 172,231 ****
          poll_fun(timeout, map)
  
! class dispatcher:
  
      debug = 0
-     connected = 0
-     accepting = 0
-     closing = 0
-     addr = None
  
      def __init__(self, sock=None, map=None):
          if map is None:
!             self._map = socket_map
!         else:
!             self._map = map
  
          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
!             # be connected?
!             try:
!                 self.addr = sock.getpeername()
!             except socket.error:
!                 # The addr isn't crucial
!                 pass
          else:
!             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 = self._map
!         map[self._fileno] = self
  
!     def del_channel(self, map=None):
!         fd = self._fileno
!         if map is None:
!             map = self._map
!         if map.has_key(fd):
!             #self.log_info('closing channel %d:%s' % (fd, self))
!             del map[fd]
!         self._fileno = None
  
      def create_socket(self, family, type):
--- 201,359 ----
          poll_fun(timeout, map)
  
! class _closed_socket(object):
!     __slots__ = []
!     def _dummy(*args):
!         raise socket.error(EBADF, 'Bad file descriptor')
!     __getattr__ = _dummy
! 
! class idispatcher(object):
! 
!     def __repr__(self):
!         status = [self.__class__.__module__+'.'+self.__class__.__name__+'['+str(self.fileno())+']']
!         try:
!             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))
!         except AttributeError:
!             pass
!         # On some systems (RH10) id() can be a negative number. 
!         # work around this.
!         MAX = 2L*sys.maxint+1
!         return '<%s at %#x>' % (' '.join(status), id(self)&MAX)
! 
!     # log and log_info may be overridden to provide more sophisticated
!     # logging and warning methods. In general, log is for 'hit' logging
!     # 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 fileno(self):
!         raise NotImplementedError
! 
!     def create_socket(self, family, type):
!         raise NotImplementedError
! 
!     def set_socket(self, sock):
!         raise NotImplementedError
! 
!     def set_reuse_addr(self):
!         raise NotImplementedError
! 
!     def listen(self, num):
!         raise NotImplementedError
! 
!     def bind(self, addr):
!         raise NotImplementedError
! 
!     def connect(self, address):
!         raise NotImplementedError
! 
!     def accept(self):
!         raise NotImplementedError
! 
!     def send(self, data):
!         raise NotImplementedError
! 
!     def recv(self, buffer_size):
!         raise NotImplementedError
! 
!     def close(self):
!         raise NotImplementedError
! 
!     def readable(self):
!         return False
! 
!     def pending_read(self):
!         return False
! 
!     def writable(self):
!         return False
! 
!     def pending_write(self):
!         return False
! 
!     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,
!                 t,
!                 v,
!                 tbinfo
!                 ),
!             'error'
!             )
!         self.close()
! 
!     def handle_read(self):
!         self.log_info('unhandled read event on %s' % (repr(self)), 'warning')
! 
!     def handle_write(self):
!         self.log_info('unhandled write event on %s' % (repr(self)), 'warning')
! 
!     def handle_connect(self):
!         self.log_info('unhandled connect event on %s' % (repr(self)), 'warning')
! 
!     def handle_accept(self):
!         self.log_info('unhandled accept event on %s' % (repr(self)), 'warning')
! 
!     def handle_close(self):
!         self.log_info('unhandled close event on %s' % (repr(self)), 'warning')
!         self.close()
! 
! class dispatcher(idispatcher):
  
      debug = 0
  
      def __init__(self, sock=None, map=None):
+         idispatcher.__init__(self)
          if map is None:
!             map = socket_map
!         self._map = map
!         self.connected = False
!         self.accepting = False
!         self.addr = None
!         self.pending_accept = None
  
          if sock:
!             self.set_socket(sock)
          else:
!             self.socket = _closed_socket()
  
!     def fileno(self):
!         return self._fileno
  
!     def add_channel(self):
!         if self.debug:
!             self.log_info('adding channel %d:%s' % (self._fileno, self))
!         self._map[self._fileno] = self
  
!     def del_channel(self):
!         if self._fileno is not None:
!             if self.debug:
!                 self.log_info('closing channel %d:%s' % (self._fileno, self))
!             try:
!                 del self._map[self._fileno]
!             except:
!                 pass
!             self._fileno = None
  
      def create_socket(self, family, type):
***************
*** 236,244 ****
          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):
--- 364,384 ----
          self.add_channel()
  
!     def set_socket(self, sock):
          self.socket = sock
! 
!         self.socket.setblocking(0)
!         self.connected = False
!         try:
!             self.addr = sock.getpeername()
!             self.connected = True
!         except socket.error, err:
!             if err[0] == ENOTCONN:
!                 pass
!             else:
!                 raise
! 
!         fd = sock.fileno()
!         self._fileno = fd
!         self.add_channel()
  
      def set_reuse_addr(self):
***************
*** 259,272 ****
      # ==================================================
  
!     def readable(self):
!         return True
  
!     if os.name == 'mac':
!         # 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
  
--- 399,418 ----
      # ==================================================
  
!     def _readable(self):
!         if self.accepting:
!             # wait for readable event for accepting socket (man accept)
!             return True
!         if self.connected:
!             return self.readable()
!         else:
!             return False
  
!     def _writable(self):
!         if self.accepting:
!             return False
!         if self.connected:
!             return self.writable()
!         else:
!             # wait for writable event for connecting socket (man connect)
              return True
  
***************
*** 276,280 ****
  
      def listen(self, num):
!         self.accepting = 1
          if os.name == 'nt' and num > 5:
              num = 1
--- 422,426 ----
  
      def listen(self, num):
!         self.accepting = True
          if os.name == 'nt' and num > 5:
              num = 1
***************
*** 286,290 ****
  
      def connect(self, address):
!         self.connected = 0
          err = self.socket.connect_ex(address)
          # XXX Should interpret Winsock return values
--- 432,436 ----
  
      def connect(self, address):
!         self.connected = False
          err = self.socket.connect_ex(address)
          # XXX Should interpret Winsock return values
***************
*** 293,311 ****
          if err in (0, EISCONN):
              self.addr = address
!             self.connected = 1
              self.handle_connect()
          else:
!             raise socket.error, err
  
      def accept(self):
!         # XXX can return either an address pair or None
!         try:
!             conn, addr = self.socket.accept()
!             return conn, addr
!         except socket.error, why:
!             if why[0] == EWOULDBLOCK:
!                 pass
!             else:
!                 raise socket.error, why
  
      def send(self, data):
--- 439,451 ----
          if err in (0, EISCONN):
              self.addr = address
!             self.connected = True
              self.handle_connect()
          else:
!             raise socket.error, (err, errorcode[err])
  
      def accept(self):
!         res = self.pending_accept
!         self.pending_accept = None
!         return res
  
      def send(self, data):
***************
*** 316,322 ****
              if why[0] == EWOULDBLOCK:
                  return 0
              else:
!                 raise socket.error, why
!             return 0
  
      def recv(self, buffer_size):
--- 456,465 ----
              if why[0] == EWOULDBLOCK:
                  return 0
+             if why[0] in (ECONNRESET, ENOTCONN, ESHUTDOWN):
+                 self.connected = False
+                 self.handle_close()
+                 return 0
              else:
!                 raise
  
      def recv(self, buffer_size):
***************
*** 326,329 ****
--- 469,473 ----
                  # a closed connection is indicated by signaling
                  # a read condition, and having recv() return 0.
+                 self.connected = False
                  self.handle_close()
                  return ''
***************
*** 331,342 ****
                  return data
          except socket.error, why:
!             # winsock sometimes throws ENOTCONN
!             if why[0] in [ECONNRESET, ENOTCONN, ESHUTDOWN]:
                  self.handle_close()
                  return ''
              else:
!                 raise socket.error, why
  
      def close(self):
          self.del_channel()
          self.socket.close()
--- 475,490 ----
                  return data
          except socket.error, why:
!             if why[0] in (ECONNRESET, ENOTCONN, ESHUTDOWN):
!                 self.connected = False
                  self.handle_close()
                  return ''
              else:
!                 raise
  
      def close(self):
+         self.connected = False
+         self.accepting = False
+         self.addr = None
+         self.pending_accept = None
          self.del_channel()
          self.socket.close()
***************
*** 347,423 ****
          return getattr(self.socket, attr)
  
-     # log and log_info may be overridden to provide more sophisticated
-     # logging and warning methods. In general, log is for 'hit' logging
-     # 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
!             # that we are connected
!             if not self.connected:
!                 self.connected = 1
              self.handle_accept()
-         elif not self.connected:
-             self.handle_connect()
-             self.connected = 1
-             self.handle_read()
          else:
              self.handle_read()
  
      def handle_write_event(self):
!         # getting a write implies that we are connected
!         if not self.connected:
!             self.handle_connect()
!             self.connected = 1
!         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,
!                 t,
!                 v,
!                 tbinfo
!                 ),
!             'error'
!             )
!         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()
  
  # ---------------------------------------------------------------------------
--- 495,531 ----
          return getattr(self.socket, attr)
  
      def handle_read_event(self):
          if self.accepting:
!             try:
!                 self.pending_accept = self.socket.accept()
!             except socket.error:
!                 # treat errors after accept() as EWOULDBLOCK
!                 return
!             except:
!                 raise
              self.handle_accept()
          else:
+             # impossible get read event for connecting socket
+             assert(self.connected)
              self.handle_read()
  
      def handle_write_event(self):
!         # impossible get write event for accepting socket
!         assert(not self.accepting)
!         if self.connected:
!             self.handle_write()
!         else:
!             err = self.socket.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR)
!             if err != 0:
!                 raise socket.error, (err, errorcode[err])
!             else:
!                 self.connected = True
!                 self.handle_connect()
  
      def handle_expt_event(self):
!         err = self.socket.getsockopt(socket.SOL_SOCKET, socket.SO_ERROR)
!         assert(err != 0)
!         raise socket.error, (err, errorcode[err])
  
  
  # ---------------------------------------------------------------------------
***************
*** 476,480 ****
          map = socket_map
      for x in map.values():
!         x.socket.close()
      map.clear()
  
--- 584,594 ----
          map = socket_map
      for x in map.values():
!         try:
!             x.close()
!         except OSError, x:
!             if x[0] == EBADF:
!                 pass
!             else:
!                 raise
      map.clear()
  
***************
*** 502,516 ****
              self.fd = fd
  
!         def recv(self, *args):
              return os.read(self.fd, *args)
  
!         def send(self, *args):
              return os.write(self.fd, *args)
  
!         read = recv
!         write = send
  
          def close(self):
!             return os.close(self.fd)
  
          def fileno(self):
--- 616,630 ----
              self.fd = fd
  
!         def read(self, *args):
              return os.read(self.fd, *args)
  
!         def write(self, *args):
              return os.write(self.fd, *args)
  
!         recv = read
!         send = write
  
          def close(self):
!             os.close(self.fd)
  
          def fileno(self):
***************
*** 519,530 ****
      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):
--- 633,644 ----
      class file_dispatcher(dispatcher):
  
!         def __init__(self, fd, map=None):
!             dispatcher.__init__(self, None, map)
!             self.connected = True
!             self.set_file(fd)
              # set it to non-blocking mode
!             flags = fcntl.fcntl(self._fileno, fcntl.F_GETFL, 0)
              flags = flags | os.O_NONBLOCK
!             fcntl.fcntl(self._fileno, fcntl.F_SETFL, flags)
  
          def set_file(self, fd):
***************
*** 532,533 ****
--- 646,648 ----
              self.socket = file_wrapper(fd)
              self.add_channel()
+ 

Index: asynchat.py
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/asyncore/asynchat.py,v
retrieving revision 1.1
retrieving revision 1.2
diff -C2 -d -r1.1 -r1.2
*** asynchat.py	21 Mar 2004 19:14:19 -0000	1.1
--- asynchat.py	21 Mar 2004 19:15:02 -0000	1.2
***************
*** 51,55 ****
  from collections import deque
  
! class async_chat (asyncore.dispatcher):
      """This is an abstract class.  You must derive from this class, and add
      the two methods collect_incoming_data() and found_terminator()"""
--- 51,55 ----
  from collections import deque
  
! class iasync_chat (asyncore.idispatcher):
      """This is an abstract class.  You must derive from this class, and add
      the two methods collect_incoming_data() and found_terminator()"""
***************
*** 60,68 ****
      ac_out_buffer_size      = 4096
  
!     def __init__ (self, conn=None):
          self.ac_in_buffer = ''
          self.ac_out_buffer = ''
          self.producer_fifo = fifo()
-         asyncore.dispatcher.__init__ (self, conn)
  
      def collect_incoming_data(self, data):
--- 60,68 ----
      ac_out_buffer_size      = 4096
  
!     def __init__ (self):
!         asyncore.idispatcher.__init__ (self)
          self.ac_in_buffer = ''
          self.ac_out_buffer = ''
          self.producer_fifo = fifo()
  
      def collect_incoming_data(self, data):
***************
*** 233,236 ****
--- 233,242 ----
  
  
+ class async_chat (iasync_chat, asyncore.dispatcher):
+ 
+     def __init__ (self, sock=None, map=None):
+         asyncore.dispatcher.__init__ (self, sock, map)
+         iasync_chat.__init__ (self)
+ 
  class simple_producer:
  




More information about the Python-checkins mailing list