[Zodb-checkins] CVS: Releases/Zope/lib/python/ThreadedAsync - LoopCallback.py:1.4.6.1
Guido van Rossum
guido@python.org
Tue, 5 Nov 2002 14:55:43 -0500
Update of /cvs-repository/Releases/Zope/lib/python/ThreadedAsync
In directory cvs.zope.org:/tmp/cvs-serv20451/lib/python/ThreadedAsync
Modified Files:
Tag: Zope-2_6-branch
LoopCallback.py
Log Message:
Added code to ThreadedAsync/LoopCallback.py to work around a bug in
asyncore.py: a handled signal can cause unwanted reads to happen.
=== Releases/Zope/lib/python/ThreadedAsync/LoopCallback.py 1.4 => 1.4.6.1 ===
--- Releases/Zope/lib/python/ThreadedAsync/LoopCallback.py:1.4 Wed Aug 14 18:02:00 2002
+++ Releases/Zope/lib/python/ThreadedAsync/LoopCallback.py Tue Nov 5 14:55:42 2002
@@ -29,11 +29,13 @@
module is imported, any client of the asyncore module will get
ThreadedAsync.loop() when it calls asyncore.loop().
"""
-__version__='$Revision$'[11:-2]
+__version__ = '$Revision$'[11:-2]
import asyncore
import select
import thread
+import time
+from errno import EINTR
_loop_lock = thread.allocate_lock()
_looping = None
@@ -79,7 +81,53 @@
finally:
_loop_lock.release()
-def loop (timeout=30.0, use_poll=0, map=None):
+def poll(timeout=0.0, map=None):
+ """A copy of asyncore.poll() with a bug fixed (see comment).
+
+ (asyncore.poll2() and .poll3() don't have this bug.)
+ """
+ if map is None:
+ map = asyncore.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:
+ # This part is missing in asyncore before Python 2.3
+ return
+
+ for fd in r:
+ obj = map.get(fd)
+ if obj is not None:
+ try:
+ obj.handle_read_event()
+ except asyncore.ExitNow:
+ raise asyncore.ExitNow
+ except:
+ obj.handle_error()
+
+ for fd in w:
+ obj = map.get(fd)
+ if obj is not None:
+ try:
+ obj.handle_write_event()
+ except asyncore.ExitNow:
+ raise asyncore.ExitNow
+ except:
+ obj.handle_error()
+
+def loop(timeout=30.0, use_poll=0, map=None):
"""Invoke asyncore mainloop
This function functions like the regular asyncore.loop() function
@@ -92,7 +140,7 @@
else:
poll_fun = asyncore.poll2
else:
- poll_fun = asyncore.poll
+ poll_fun = poll
if map is None:
map = asyncore.socket_map
@@ -103,11 +151,10 @@
_stop_loop()
# Woo hoo!
-asyncore.loop=loop
+asyncore.loop = loop
# What the heck did we just do?
#
# Well, the thing is, we want to work with other asyncore aware
# code. In particular, we don't necessarily want to make someone
# import this module just to start or loop.
-#