When Chris Rolliston implemented a simple threaded queue class using TMonitor, I was quite ecstatic. Finally I will be able to compare my lock-free queue with a threaded implementation! (That’s something I wanted to do for a long time but I never found a willpower to write a locking queue.)
My elation continued while I was coding my test app and while I tested my own queue. And then I plugged in Chris’ queue and … everything went downhill :( Immediately, my test app started crashing. At first it looked like the bug was in Chris’ code, but when I enabled debug DCUs, debugger pointed to a very unlikely location – TMonitor. Unlikely because of two reason – because I know that Delphi people take quality to the heart and test the code and because I know Allen is an experienced guy who writes excellent code.
Please note that I’m not saying that there’s a bug in TMonitor – at least at the moment I’m not. It just looks that way. I would have to do some heavy debugging to prove this and at the moment my head is too full of pollen and antihistamine to do such work. That’s why I’m asking experienced Delphi programmers to jump in and help me find the true reason of the problem - TMonitor, TSimpleThreadedQueue or my test program.
To run the test program you would need fairly fresh OmniThreadLibrary (at least release 899) and Delphi XE. Download the source, make sure that path includes OmniThreadLibrary, recompile and run. Most probably it would help to have four cores to exhibit the problem although I was able to reproduce it on only one.
Anyway, run the application and click the “Bug?” button. If you see something like
popping up, then you have repeated the problem.
In my testing, clicking Break opens debugger in System.pas. If you get SimpleThreadedQueue.pas or speedtest1.pas instead, then most probably you don’t have debug DCUs enabled.
The test code in StartTest2 creates one writer and two reader threads. In my testing the problem occurs when one writer and one reader already completed their work and only the last reader is running. When this last reader calls Dequeue, TMonitor.Wait gets called. This one calls RemoveWaiter and crash occurs.
This is all I know about the problem at this moment. If you feel capable and can spare yourself some time, please download the app and try to help me finding the real cause for this crash. Thanks!
This bug was fixed in Delphi XE2.