Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit da85a27

Browse files
committed
Match Sam Rushing's current version of asyncore.py and asynchat.py
(SF patch 101447, fixing PR#113704)
1 parent 72e48bd commit da85a27

2 files changed

Lines changed: 126 additions & 81 deletions

File tree

Lib/asynchat.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# -*- Mode: Python; tab-width: 4 -*-
2-
# Id: asynchat.py,v 2.23 1999/05/01 04:49:24 rushing Exp
2+
# Id: asynchat.py,v 2.25 1999/11/18 11:01:08 rushing Exp
33
# Author: Sam Rushing <[email protected]>
44

55
# ======================================================================
@@ -123,7 +123,9 @@ def handle_read (self):
123123
index = string.find (self.ac_in_buffer, terminator)
124124
if index != -1:
125125
# we found the terminator
126-
self.collect_incoming_data (self.ac_in_buffer[:index])
126+
if index > 0:
127+
# don't bother reporting the empty string (source of subtle bugs)
128+
self.collect_incoming_data (self.ac_in_buffer[:index])
127129
self.ac_in_buffer = self.ac_in_buffer[index+terminator_len:]
128130
# This does the Right Thing if the terminator is changed here.
129131
self.found_terminator()
@@ -220,10 +222,11 @@ def initiate_send (self):
220222
def discard_buffers (self):
221223
# Emergencies only!
222224
self.ac_in_buffer = ''
223-
self.ac_out_buffer == ''
225+
self.ac_out_buffer = ''
224226
while self.producer_fifo:
225227
self.producer_fifo.pop()
226228

229+
227230
class simple_producer:
228231

229232
def __init__ (self, data, buffer_size=512):
@@ -287,7 +290,7 @@ def pop (self):
287290
## return result
288291

289292
# yes, this is about twice as fast, but still seems
290-
# to be negligible CPU. The previous could do about 290
293+
# to be negligible CPU. The previous version could do about 290
291294
# searches/sec. the new one about 555/sec.
292295

293296
import regex

Lib/asyncore.py

Lines changed: 119 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# -*- Mode: Python; tab-width: 4 -*-
2-
# Id: asyncore.py,v 2.40 1999/05/27 04:08:25 rushing Exp
2+
# Id: asyncore.py,v 2.51 2000/09/07 22:29:26 rushing Exp
33
# Author: Sam Rushing <[email protected]>
44

55
# ======================================================================
@@ -46,6 +46,7 @@
4646
sophisticated high-performance network servers and clients a snap.
4747
"""
4848

49+
import exceptions
4950
import select
5051
import socket
5152
import string
@@ -62,70 +63,100 @@
6263
else:
6364
from errno import EALREADY, EINPROGRESS, EWOULDBLOCK, ECONNRESET, ENOTCONN, ESHUTDOWN
6465

65-
socket_map = {}
66+
try:
67+
socket_map
68+
except NameError:
69+
socket_map = {}
6670

67-
def poll (timeout=0.0):
68-
if socket_map:
71+
class ExitNow (exceptions.Exception):
72+
pass
73+
74+
DEBUG = 0
75+
76+
def poll (timeout=0.0, map=None):
77+
global DEBUG
78+
if map is None:
79+
map = socket_map
80+
if map:
6981
r = []; w = []; e = []
70-
for s in socket_map.keys():
71-
if s.readable():
72-
r.append (s)
73-
if s.writable():
74-
w.append (s)
82+
for fd, obj in map.items():
83+
if obj.readable():
84+
r.append (fd)
85+
if obj.writable():
86+
w.append (fd)
87+
r,w,e = select.select (r,w,e, timeout)
7588

76-
(r,w,e) = select.select (r,w,e, timeout)
89+
if DEBUG:
90+
print r,w,e
7791

78-
for x in r:
92+
for fd in r:
7993
try:
80-
x.handle_read_event()
81-
except:
82-
x.handle_error()
83-
for x in w:
94+
obj = map[fd]
95+
try:
96+
obj.handle_read_event()
97+
except ExitNow:
98+
raise ExitNow
99+
except:
100+
obj.handle_error()
101+
except KeyError:
102+
pass
103+
104+
for fd in w:
84105
try:
85-
x.handle_write_event()
86-
except:
87-
x.handle_error()
106+
obj = map[fd]
107+
try:
108+
obj.handle_write_event()
109+
except ExitNow:
110+
raise ExitNow
111+
except:
112+
obj.handle_error()
113+
except KeyError:
114+
pass
88115

89-
def poll2 (timeout=0.0):
116+
def poll2 (timeout=0.0, map=None):
90117
import poll
118+
if map is None:
119+
map=socket_map
91120
# timeout is in milliseconds
92121
timeout = int(timeout*1000)
93-
if socket_map:
94-
fd_map = {}
95-
for s in socket_map.keys():
96-
fd_map[s.fileno()] = s
122+
if map:
97123
l = []
98-
for fd, s in fd_map.items():
124+
for fd, obj in map.items():
99125
flags = 0
100-
if s.readable():
126+
if obj.readable():
101127
flags = poll.POLLIN
102-
if s.writable():
128+
if obj.writable():
103129
flags = flags | poll.POLLOUT
104130
if flags:
105131
l.append ((fd, flags))
106132
r = poll.poll (l, timeout)
107133
for fd, flags in r:
108-
s = fd_map[fd]
109134
try:
110-
if (flags & poll.POLLIN):
111-
s.handle_read_event()
112-
if (flags & poll.POLLOUT):
113-
s.handle_write_event()
114-
if (flags & poll.POLLERR):
115-
s.handle_expt_event()
116-
except:
117-
s.handle_error()
118-
135+
obj = map[fd]
136+
try:
137+
if (flags & poll.POLLIN):
138+
obj.handle_read_event()
139+
if (flags & poll.POLLOUT):
140+
obj.handle_write_event()
141+
except ExitNow:
142+
raise ExitNow
143+
except:
144+
obj.handle_error()
145+
except KeyError:
146+
pass
119147

120-
def loop (timeout=30.0, use_poll=0):
148+
def loop (timeout=30.0, use_poll=0, map=None):
121149

122150
if use_poll:
123151
poll_fun = poll2
124152
else:
125153
poll_fun = poll
126154

127-
while socket_map:
128-
poll_fun (timeout)
155+
if map is None:
156+
map=socket_map
157+
158+
while map:
159+
poll_fun (timeout, map)
129160

130161
class dispatcher:
131162
debug = 0
@@ -134,9 +165,9 @@ class dispatcher:
134165
closing = 0
135166
addr = None
136167

137-
def __init__ (self, sock=None):
168+
def __init__ (self, sock=None, map=None):
138169
if sock:
139-
self.set_socket (sock)
170+
self.set_socket (sock, map)
140171
# I think it should inherit this anyway
141172
self.socket.setblocking (0)
142173
self.connected = 1
@@ -163,27 +194,31 @@ def __repr__ (self):
163194

164195
return '<__repr__ (self) failed for object at %x (addr=%s)>' % (id(self),ar)
165196

166-
def add_channel (self):
167-
if __debug__:
168-
self.log ('adding channel %s' % self)
169-
socket_map [self] = 1
197+
def add_channel (self, map=None):
198+
#self.log_info ('adding channel %s' % self)
199+
if map is None:
200+
map=socket_map
201+
map [self._fileno] = self
170202

171-
def del_channel (self):
172-
if socket_map.has_key (self):
173-
if __debug__:
174-
self.log ('closing channel %d:%s' % (self.fileno(), self))
175-
del socket_map [self]
203+
def del_channel (self, map=None):
204+
fd = self._fileno
205+
if map is None:
206+
map=socket_map
207+
if map.has_key (fd):
208+
#self.log_info ('closing channel %d:%s' % (fd, self))
209+
del map [fd]
176210

177211
def create_socket (self, family, type):
178212
self.family_and_type = family, type
179213
self.socket = socket.socket (family, type)
180214
self.socket.setblocking(0)
215+
self._fileno = self.socket.fileno()
181216
self.add_channel()
182217

183-
def set_socket (self, socket):
184-
# This is done so we can be called safely from __init__
185-
self.__dict__['socket'] = socket
186-
self.add_channel()
218+
def set_socket (self, sock, map=None):
219+
self.__dict__['socket'] = sock
220+
self._fileno = sock.fileno()
221+
self.add_channel (map)
187222

188223
def set_reuse_addr (self):
189224
# try to re-use a server port if possible
@@ -284,12 +319,19 @@ def close (self):
284319

285320
# cheap inheritance, used to pass all other attribute
286321
# references to the underlying socket object.
287-
# NOTE: this may be removed soon for performance reasons.
288322
def __getattr__ (self, attr):
289323
return getattr (self.socket, attr)
290324

325+
# log and log_info maybe overriden to provide more sophisitcated
326+
# logging and warning methods. In general, log is for 'hit' logging
327+
# and 'log_info' is for informational, warning and error logging.
328+
291329
def log (self, message):
292-
print 'log:', message
330+
sys.stderr.write ('log: %s\n' % str(message))
331+
332+
def log_info (self, message, type='info'):
333+
if __debug__ or type != 'info':
334+
print '%s: %s' % (type, message)
293335

294336
def handle_read_event (self):
295337
if self.accepting:
@@ -324,39 +366,34 @@ def handle_error (self):
324366
except:
325367
self_repr = '<__repr__ (self) failed for object at %0x>' % id(self)
326368

327-
print (
369+
self.log_info (
328370
'uncaptured python exception, closing channel %s (%s:%s %s)' % (
329371
self_repr,
330372
t,
331373
v,
332374
tbinfo
333-
)
375+
),
376+
'error'
334377
)
335378
self.close()
336379

337380
def handle_expt (self):
338-
if __debug__:
339-
self.log ('unhandled exception')
381+
self.log_info ('unhandled exception', 'warning')
340382

341383
def handle_read (self):
342-
if __debug__:
343-
self.log ('unhandled read event')
384+
self.log_info ('unhandled read event', 'warning')
344385

345386
def handle_write (self):
346-
if __debug__:
347-
self.log ('unhandled write event')
387+
self.log_info ('unhandled write event', 'warning')
348388

349389
def handle_connect (self):
350-
if __debug__:
351-
self.log ('unhandled connect event')
390+
self.log_info ('unhandled connect event', 'warning')
352391

353392
def handle_accept (self):
354-
if __debug__:
355-
self.log ('unhandled accept event')
393+
self.log_info ('unhandled accept event', 'warning')
356394

357395
def handle_close (self):
358-
if __debug__:
359-
self.log ('unhandled close event')
396+
self.log_info ('unhandled close event', 'warning')
360397
self.close()
361398

362399
# ---------------------------------------------------------------------------
@@ -382,7 +419,7 @@ def writable (self):
382419

383420
def send (self, data):
384421
if self.debug:
385-
self.log ('sending %s' % repr(data))
422+
self.log_info ('sending %s' % repr(data))
386423
self.out_buffer = self.out_buffer + data
387424
self.initiate_send()
388425

@@ -396,7 +433,7 @@ def compact_traceback ():
396433
while 1:
397434
tbinfo.append ((
398435
tb.tb_frame.f_code.co_filename,
399-
tb.tb_frame.f_code.co_name,
436+
tb.tb_frame.f_code.co_name,
400437
str(tb.tb_lineno)
401438
))
402439
tb = tb.tb_next
@@ -416,11 +453,12 @@ def compact_traceback ():
416453
) + ']'
417454
return (file, function, line), t, v, info
418455

419-
def close_all ():
420-
global socket_map
421-
for x in socket_map.keys():
456+
def close_all (map=None):
457+
if map is None:
458+
map=socket_map
459+
for x in map.values():
422460
x.socket.close()
423-
socket_map.clear()
461+
map.clear()
424462

425463
# Asynchronous File I/O:
426464
#
@@ -449,9 +487,12 @@ def __init__ (self, fd):
449487
def recv (self, *args):
450488
return apply (os.read, (self.fd,)+args)
451489

452-
def write (self, *args):
490+
def send (self, *args):
453491
return apply (os.write, (self.fd,)+args)
454492

493+
read = recv
494+
write = send
495+
455496
def close (self):
456497
return os.close (self.fd)
457498

@@ -469,6 +510,7 @@ def __init__ (self, fd):
469510
self.set_file (fd)
470511

471512
def set_file (self, fd):
513+
self._fileno = fd
472514
self.socket = file_wrapper (fd)
473515
self.add_channel()
474516

0 commit comments

Comments
 (0)