tag:blogger.com,1999:blog-29331675.post5331577944348780410..comments2024-03-05T17:37:00.995+01:00Comments on The Delphi Geek: TMonitor bug?gabr42http://www.blogger.com/profile/06903558857617342477noreply@blogger.comBlogger21125tag:blogger.com,1999:blog-29331675.post-5414503627759201632012-03-14T13:21:13.205+01:002012-03-14T13:21:13.205+01:00Hi! I have created a patch for TMonitor in Delphi ...Hi! I have created a patch for TMonitor in Delphi XE, based on Christian Gudrian's comment above. It can be downloaded from here: http://href.hu/x/hdu3Balázshttps://www.blogger.com/profile/16110216800846576171noreply@blogger.comtag:blogger.com,1999:blog-29331675.post-90868639116804219992011-08-26T10:37:34.936+02:002011-08-26T10:37:34.936+02:00Hi
We seem to have this problem affecting us wit...Hi <br /><br />We seem to have this problem affecting us with Delphi XE.<br /><br />It is affecting the datasnap callbacks in our application.<br /><br />we can simulate with a small app, is there any way we can do these changes in Delphi XE system.pas and compile the DCUAnonymousnoreply@blogger.comtag:blogger.com,1999:blog-29331675.post-9414861445510579212011-06-24T13:40:17.218+02:002011-06-24T13:40:17.218+02:00Hi!
Here's the patch that can be applied to S...Hi!<br /><br />Here's the patch that can be applied to SyncObjs.pas:<br /><br />diff --git a/SyncObjs.pas b/SyncObjs.pas<br />index 4239a0b..f5382d9 100644<br />--- a/SyncObjs.pas<br />+++ b/SyncObjs.pas<br />@@ -953,7 +953,7 @@ begin<br /> begin<br /> WaitQueue := LockQueue;<br /> try<br />- Last := WaitQueue.Next;<br />+ Last := WaitQueue;<br /> Walker := Last.Next;<br /> while Walker <> WaitQueue do<br /> begin<br />@@ -969,7 +969,10 @@ begin<br /> if Walker.Next = Walker then<br /> WaitQueue := nil<br /> else<br />- WaitQueue := Last;<br />+ begin<br />+ WaitQueue := Walker.Next;<br />+ Last.Next := WaitQueue;<br />+ end;<br /> finally<br /> UnlockQueue(WaitQueue);<br /> end;<br /><br /><br />System.TMonitor.RemoveWaiter can be fixed accordingly.Christian Gudrianhttps://www.blogger.com/profile/08589740832179716701noreply@blogger.comtag:blogger.com,1999:blog-29331675.post-64152862231664759412011-06-24T13:30:57.199+02:002011-06-24T13:30:57.199+02:00Hi!
Here's the patch that can be applied to S...Hi!<br /><br />Here's the patch that can be applied to SyncObjs.pas:<br /><br />diff --git a/SyncObjs.pas b/SyncObjs.pas<br />index 4239a0b..f5382d9 100644<br />--- a/SyncObjs.pas<br />+++ b/SyncObjs.pas<br />@@ -953,7 +953,7 @@ begin<br /> begin<br /> WaitQueue := LockQueue;<br /> try<br />- Last := WaitQueue.Next;<br />+ Last := WaitQueue;<br /> Walker := Last.Next;<br /> while Walker <> WaitQueue do<br /> begin<br />@@ -969,7 +969,10 @@ begin<br /> if Walker.Next = Walker then<br /> WaitQueue := nil<br /> else<br />- WaitQueue := Last;<br />+ begin<br />+ WaitQueue := Walker.Next;<br />+ Last.Next := WaitQueue;<br />+ end;<br /> finally<br /> UnlockQueue(WaitQueue);<br /> end;<br /><br />System.TMonitor.RemoveWaiter can be patched accordingly.Christian Gudrianhttps://www.blogger.com/profile/08589740832179716701noreply@blogger.comtag:blogger.com,1999:blog-29331675.post-56462541745144979102011-06-21T16:55:58.182+02:002011-06-21T16:55:58.182+02:00With Delphi 2009 (after commenting out TStopWatch ...With Delphi 2009 (after commenting out TStopWatch related code and changing Line 79 to "if not TMonitor.Wait(FQueue, LongWord(Timeout)) then Exit(wrTimeout);", no exception is thrown. Instead the application freezes, the log shows:<br /><br />Debug Output: Exiting writer Process speedtest.exe (3928)<br />Debug Output: Awaited writers Process speedtest.exe (3928)<br />Debug Output: Exiting reader Process speedtest.exe (3928)<br /><br />Looks like it is broken in a different way?Michael Justinhttps://www.blogger.com/profile/08260186770240506216noreply@blogger.comtag:blogger.com,1999:blog-29331675.post-34069861329505411722011-06-09T12:18:34.968+02:002011-06-09T12:18:34.968+02:00@Michel: I think the test app should work in 2009 ...@Michel: I think the test app should work in 2009 (but I may be wrong).gabr42https://www.blogger.com/profile/06903558857617342477noreply@blogger.comtag:blogger.com,1999:blog-29331675.post-84055273896627384082011-06-09T10:41:07.065+02:002011-06-09T10:41:07.065+02:00Is XE or 2010 required to compile/run the test app...Is XE or 2010 required to compile/run the test app? Or could it work with Delphi 2009?Michael Justinhttps://www.blogger.com/profile/08260186770240506216noreply@blogger.comtag:blogger.com,1999:blog-29331675.post-57364092976226677042011-06-06T15:27:37.198+02:002011-06-06T15:27:37.198+02:00When I initially posted the bug back in 2009, I...When I initially posted the bug back in 2009, I've also attached a patch that fixes at least the error in SyncObjs.pas. That patch, however, disappeared from the report (presumably because it got overridden by an attachment that got added later). I'll have a look if I can re-attach the patch.Christian Gudrianhttps://www.blogger.com/profile/08589740832179716701noreply@blogger.comtag:blogger.com,1999:blog-29331675.post-69493886652155971222011-05-26T11:54:48.895+02:002011-05-26T11:54:48.895+02:00That's a 2009 bug, ouch, I guess it means that...That's a 2009 bug, ouch, I guess it means that TMonitor hasn't been used much (if any) in production code out there since it was introduced... Give us our 4 bytes per instance back! ;)Erichttp://delphitools.info/noreply@blogger.comtag:blogger.com,1999:blog-29331675.post-23482300712122129022011-05-26T11:15:22.804+02:002011-05-26T11:15:22.804+02:00@Chris, Moritz, gabr
So the same bug appears in Sy...@Chris, Moritz, gabr<br />So the same bug appears in SynObjs.pas AND in System.pas... **Sigh** Code duplication...<br /> <br />In the end, 2 bugs in 2 different units could be solved with just one shot ! That's pretty good news !Thierry Pellennoreply@blogger.comtag:blogger.com,1999:blog-29331675.post-36387047674774806692011-05-25T21:07:47.545+02:002011-05-25T21:07:47.545+02:00@Moritz: Yes, that seems to be the same problem. S...@Moritz: Yes, that seems to be the same problem. Shame on Embarcadero for not fixing this with a hotfix!gabr42https://www.blogger.com/profile/06903558857617342477noreply@blogger.comtag:blogger.com,1999:blog-29331675.post-21600397780595703542011-05-25T21:06:19.678+02:002011-05-25T21:06:19.678+02:00Sorry, now I see that the discussion Chris pointed...Sorry, now I see that the discussion Chris pointed to also mentions this report.Moritz Beutelhttp://www.audacia-software.de/noreply@blogger.comtag:blogger.com,1999:blog-29331675.post-53166836360439942592011-05-25T21:05:11.078+02:002011-05-25T21:05:11.078+02:00This report might be interesting:
Report No: 7841...This report might be interesting:<br /><br />Report No: 78415 Status: Open<br />AV in TInternalConditionVariable.RemoveWaiter<br />http://qc.embarcadero.com/wc/qcmain.aspx?d=78415<br />QCWIN:Defect_No=78415Moritz Beutelhttp://www.audacia-software.de/noreply@blogger.comtag:blogger.com,1999:blog-29331675.post-61930287978996126032011-05-24T21:04:48.273+02:002011-05-24T21:04:48.273+02:00@Leif: Yes, it looks like this usage of TMonitor d...@Leif: Yes, it looks like this usage of TMonitor doesn't support multiple consumers. Too bad - especially as it makes TThreadedQueue useless. :(<br /><br />@Iztok: I'll make sure to test with your queue too.<br /><br />@Thierry: Your guess is as good as mine (at this moment).gabr42https://www.blogger.com/profile/06903558857617342477noreply@blogger.comtag:blogger.com,1999:blog-29331675.post-3315277453673386582011-05-24T20:57:50.105+02:002011-05-24T20:57:50.105+02:00Funnily enough, I actually asked a similar questio...Funnily enough, I actually asked a similar question back in February: https://forums.embarcadero.com/thread.jspa?messageID=320898&tstart=0#320898. Leaving it for a bit, a few months later I looked at TMonitor again and came to the conclusion it did actually work if used more simply than I was originally attempting to use it. Obviously not though!Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-29331675.post-70791896819762523902011-05-24T20:27:24.259+02:002011-05-24T20:27:24.259+02:00Hi,
I tested your code with the TThreadedQueue and...Hi,<br />I tested your code with the TThreadedQueue and the same error appeared. This is the same error as I reported in the link given above. I'm not the man to pinpoint what's going on in TMonitor. Looks like a job for Allen Bauer.Leif Uneushttp://www.opsis.senoreply@blogger.comtag:blogger.com,1999:blog-29331675.post-56247841289166967542011-05-24T16:47:22.780+02:002011-05-24T16:47:22.780+02:00Maybe the "while Walker <> FWaitQueue d...Maybe the "while Walker <> FWaitQueue do" loop could be replaced by something like this:<br /><br />repeat<br /> if Walker = @WaitingThread then<br /> begin<br /> Last.Next := Walker.Next;<br /> Break;<br /> end;<br /> Last := Walker;<br /> Walker := Walker.Next;<br />until Last = FWaitQueue.Next;<br /><br />(tested only with a pen and a sheet of paper !)Thierry Pellennoreply@blogger.comtag:blogger.com,1999:blog-29331675.post-42522252233794356782011-05-24T15:55:41.257+02:002011-05-24T15:55:41.257+02:00Oh the code is in the threading unit from download...Oh the code is in the threading unit from download.Iztok Kacinhttp://www.cromis.net/blognoreply@blogger.comtag:blogger.com,1999:blog-29331675.post-49691819144322513632011-05-24T15:54:28.739+02:002011-05-24T15:54:28.739+02:00I have written a locking queue some time ago. I te...I have written a locking queue some time ago. I tested it on quad core processor and found out that in almost all cases it is just slightly slower then you own lock free implementation. There is very small difference. Much of the difference comes from TAnyValue being slower most of the time then TOmniValue, because I use interfaces. I wrote about this improvement briefly here: http://www.cromis.net/blog/2011/03/new-version-of-simplestorage-and-other-updates/<br /><br />You can find the code on my download page. I also have the test somewhere still and can mail it to you if you like.Iztok Kacinhttp://www.cromis.net/blognoreply@blogger.comtag:blogger.com,1999:blog-29331675.post-25725777103428191822011-05-24T15:21:13.771+02:002011-05-24T15:21:13.771+02:00When the queue contains only 2 elements, Walker ge...When the queue contains only 2 elements, Walker gets initialised with FWaitQueue.Next.Next (ie FWaitQueue), isn't it ?<br />As a consequence, the while loop is never executed, and the queue either gets screwed up (FWaitQueue := Last is executed, but FWaitQueue.Next is never fixed up), or it stays untouched...<br /><br />I have the same problem under Delphi 2010...Thierry Pellennoreply@blogger.comtag:blogger.com,1999:blog-29331675.post-29897407535128836672011-05-24T14:20:47.616+02:002011-05-24T14:20:47.616+02:00Gabr, see this link
stackoverflow.com/questions/4...Gabr, see this link <br />stackoverflow.com/questions/4856306/tthreadedqueue-not-capable-of-multiple-consumers<br /><br />May be related, the error in TThreadedQueue seems to be in the TMonitor.<br />I will look into your code later today.Leif Uneushttp://www.opsis.senoreply@blogger.com