[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