[Twisted-Python] Re: [Twisted-commits] Today is screw with twisted's guts day.
Andrew Bennetts
andrew-twisted at puzzling.org
Wed Nov 19 18:38:03 MST 2003
On Wed, Nov 19, 2003 at 08:12:56PM -0500, Jp Calderone wrote:
> On Thu, Nov 20, 2003 at 11:53:19AM +1100, Andrew Bennetts wrote:
[patch to keep count of items used from the list]
>
> That looks a little more complex than it needs to be. What about this
> version?
>
>
> def runUntilCurrent(self):
> """Run all pending timed calls.
> """
> if self.threadCallQueue:
> calls, self.threadCallQueue = self.threadCallQueue, []
> for (f, a, kw) in calls:
> try:
> f(*a, **kw)
> except:
> log.err()
Yeah, that looks ok too, I think. I'm less certain though... is it possible
for this to happen:
reactor thread other thread
-------------- ------------
call callFromThread
...get reference to self.threadCallQueue
call runUntilCurrent
...set self.tCQ to a new list
...do for loop
...append to now old threadCallQueue
So that again, a call can go missing? Hmm, I think this is possible, so
that version is also bad. It's also harder to reason about than my patch --
I had to disassemble it to help me think about it :)
> I considered doing it this way first, but wasn't sure if anyone relied on
> the identity of threadCallQueue (not that anyone should, but one never
> knows). If anyone thinks changing its identity should be avoided, I'd like
> this version:
>
> def runUntilCurrent(self):
> """Run all pending timed calls.
> """
> if self.threadCallQueue:
> calls = self.threadCallQueue[:]
> del self.threadCallQueue[:]
> for (f, a, kw) in calls:
> try:
> f(*a, **kw)
> except:
> log.err()
>
That's definitely racy! What if the call to callFromThread happens between
the "calls = ..." and the del statement?
A version which does
calls = self.threadCallQueue[:]
del self.threadCallQueue[:len(calls)]
Should be ok though, for the same reason my patch is (or at least I think it
is :)
The main difference between that version and my is this one involves a small
list copy, but it might still be faster than executing "count += 1" on every
loop iteration. Either way, it's at the point where I don't care :)
> I suppose reverting it entirely is an option, seeing as how no one has yet
> *actually* been bitten by the quadratic behavior (nor does it seem likely
> that anyone will be), but all other things equal, it's nicer to use O(N)
> algorithms deep down in the guts of Twisted than to use O(N**2) algorithms.
I think I'd like to see it improved to have O(N) complexity too.
-Andrew.
More information about the Twisted-Python
mailing list