[Twisted-Python] Re: [Twisted-commits] Today is screw with twisted's guts day.
Andrew Bennetts
andrew-twisted at puzzling.org
Wed Nov 19 17:53:19 MST 2003
On Wed, Nov 19, 2003 at 02:07:39PM -0700, exarkun CVS wrote:
> Index: Twisted/twisted/internet/base.py
> diff -u Twisted/twisted/internet/base.py:1.67 Twisted/twisted/internet/base.py:1.68
> --- Twisted/twisted/internet/base.py:1.67 Fri Oct 24 12:45:58 2003
> +++ Twisted/twisted/internet/base.py Wed Nov 19 14:07:38 2003
> @@ -400,12 +400,12 @@
> """Run all pending timed calls.
> """
> if self.threadCallQueue:
> - for i in range(len(self.threadCallQueue)):
> - callable, args, kw = self.threadCallQueue.pop(0)
> + for (f, a, kw) in self.threadCallQueue:
> try:
> - callable(*args, **kw)
> + f(*a, **kw)
> except:
> - log.deferr()
> + log.err()
> + del self.threadCallQueue[:]
> now = time()
> while self._pendingTimedCalls and (self._pendingTimedCalls[-1].time <= now):
> call = self._pendingTimedCalls.pop()
I think this change introduces a race condition. It's possible for a thread
to call callFromThread between the end of the for loop and the del
statement.
(callFromThread is defined as:
def callFromThread(self, f, *args, **kw):
"""See twisted.internet.interfaces.IReactorThreads.callFromThread.
"""
assert callable(f), "%s is not callable" % f
if threadable.isInIOThread():
self.callLater(0, f, *args, **kw)
else:
# lists are thread-safe in CPython, but not in Jython
# this is probably a bug in Jython, but until fixed this code
# won't work in Jython.
self.threadCallQueue.append((f, args, kw))
self.wakeUp()
)
So I think it's possible to lose thread calls. I *think* this patch will
fix it, but more eyeballs are always welcome with threaded code:
diff -u -r1.68 base.py
--- twisted/internet/base.py 19 Nov 2003 21:07:38 -0000 1.68
+++ twisted/internet/base.py 20 Nov 2003 00:52:08 -0000
@@ -400,12 +400,14 @@
"""Run all pending timed calls.
"""
if self.threadCallQueue:
+ count = 0
for (f, a, kw) in self.threadCallQueue:
try:
f(*a, **kw)
except:
log.err()
- del self.threadCallQueue[:]
+ count += 1
+ del self.threadCallQueue[:count]
now = time()
while self._pendingTimedCalls and (self._pendingTimedCalls[-1].time <= now):
call = self._pendingTimedCalls.pop()
-Andrew.
More information about the Twisted-Python
mailing list