Paul, Thanks for this - it was very helpful.
I had tried Qt 3.1.0 but it didn't seem to have improved things. I then changed the implementation of QSemaphore.__iadd__() and __isub__ so that they used ++ (and --) instead of += (and -=) when the value was one. The semaphore.py script now works with Qt 3.0.5. I haven't yet tested against Qt 3.1.0, but I feel confident it will work. Phil On Saturday 07 December 2002 9:31 pm, Paul Felix wrote: > > Qt v3.0.5 and later versions have broken threading in PyQt under Windows > > - Linux/Unix are fine. You can see the effect running the semaphore.py > > example. > > > > I had a brief email exchange with somebody when this was first noticed > > some months ago, who suggested what the change in Qt might have been to > > cause the problem. > > > > I'm now trying to get to the bottom of this - but I don't seem to have a > > record of the email exchange. > > > > Does this ring a bell with anybody - was it you? > > > > Thanks, > > Phil > > Hi Phil, > > That was me. I was able to reproduce the problem using the C++ example. > I'm using Windows 2000 and MSVC 6.0 SP5. > > To get the C++ example to lock up, try the following: > > * Change all semapahore access increment occurances from "++" to "+= 1" > * Change all semapahore access decrement occurances from "--" to "-= 1" > > Obviously, you had to make that change in the PyQt example, as the "++" and > "--" operator methods are not available. > > I sent a report to Trolltech, and Volker Hilsheimer tried to reproduce it, > but couldn't. He sent me his diffs of the semaphore example code, and it > looked like he made the proper changes -- so we were stumped and I dropped > it. I'm curious to see if you can reproduce it. > > Actually, now that you have resurrected this issue, I think I have found > the problem. It's an elusive one that involves a thread race condition, so > that may explain why Volker couldn't reproduce it... > > When a thread makes a call to acquire a semaphore's accesses, the call > blocks until the requested access count is available. When another thread > releases accesses to a semaphore, the semaphore must do the following: > > 1. Decrement the access count > 2. Release the waiting thread(s). > > That order is quite important. In the case of the operator+=() method, as > soon as it's thread is released, it's going to check the access count to > see if there are enough accesses available. If there aren't enough > accesses available, it will go back into wait mode. > > However, if you look at QSemaphore::operator-=() in qsemaphore_win.cpp, you > will see that the waiting threads are released BEFORE the access count is > decremented. If you fix that order, the semaphores example (using "+=1" > and "-=1) will work. > > Why did it stop working in Qt 3.0.5? It's all a little convoluted, but the > short answer has to do with a change in QWaitCondition:wakeAll() (in > qwaitcondition_win.cpp), where a call to Windows SetEvent() was changed to > PulseEvent(). > > Hmmm, I just looked at Qt 3.1.0, and they changed it back to calling > SetEvent()! So, the PyQt example may work with Qt 3.1.0! I wonder why > they changed it back? > > IMHO, the code in qsemaphore_win.cpp looks a bit questionable in places. > The code in qsemaphore_unix.cpp looks platform-independent to me -- it uses > QMutex and QWaitCondition only. I don't know why it couldn't be used on > Windows too. It should work, right? > > Paul _______________________________________________ PyKDE mailing list [EMAIL PROTECTED] http://mats.gmd.de/mailman/listinfo/pykde
