TDaemon and Thread Synchronization lazarus / 34-Windows ---------------------------------------------------------------------- halmariane · 2013-06-12 11:45 Hello: Yes, i know that there are more "forum threads" about this topic, but ... I explain me: There is an issue which i posted 15 days ago. http://bugs.freepascal.org/view.php?id=24511 When i want to use Components that requires Thread Synchronization, seems that in Windows does not work at all. The same code can be executed in Linux and works, but not in Windows. The same code can be executed in Delphi and works also, so: There is some real problem with TDaemon for Windows? Regards ---------------------------------------------------------------------- BigChimp · 2013-06-12 12:12 Please *attach* (as a zip file, i.e. do not write down the program test) a *compilable*, *complete* example program in that bug report, including an indication where it goes wrong. This will help developers quickly check the code and bug, as well as be useful for future regression tests. It is probably also the reason why this bug report has not been looked at for a while (remember: the devs are volunteers). ---------------------------------------------------------------------- halmariane · 2013-06-12 14:09 Quote from: BigChimp on June 12, 2013, 02:12:01 pmPlease *attach* (as a zip file, i.e. do not write down the program test) a *compilable*, *complete* example program in that bug report, including an indication where it goes wrong. This will help developers quickly check the code and bug, as well as be useful for future regression tests. It is probably also the reason why this bug report has not been looked at for a while (remember: the devs are volunteers). Yes BigChimp, you are right. It's for my age. Ok, i have uploaded one simple project there (http://bugs.freepascal.org/view.php?id=24511), and here also. Such as i wrote http://bugs.freepascal.org/view.php?id=24511 Code: [Select]// Sample Code // *********** // In this sample code, the method "IntervalEvent" is never called with Lazarus for Windows // // JUST HERE procedure TSimpleThread.Execute; begin   while not Terminated do     begin       Sleep(3000);       Inc(FCounter);       if Assigned(FOnInterval) then        Synchronize(@CallOnInterval);     end; end; QuoteSynchronize(@CallOnInterval) ...... is never synchronized The problem can be hard. There are components that requires thread synchronization with the main application that does not work in Windows with this issue (TDaemon). May be i'm wrong, it will be for my age (and my brain).     Regards QuoteDon't forget to start the service from Windows Service Manager. In linux just execute with -r param ---------------------------------------------------------------------- ChrisF · 2013-06-12 19:20 I don't know really how Synchronize is internally implemented in FPC. It seems to send a WM_NULL message, which is processed to call the CheckSynchronize proc in the main windows message loop. If I'm trying your synchronize call directly inside a simple program using a TThread and a TCustomDaemon, it's only working if I'm removing the WaitMessage call inside the concerned loop (which is definitively not a good idea), and if I implicitly call the CheckSynchronize proc myself. Modification for Unit ("fcl-extra" package must be recompiled and replaced): ($lazdir)\fpc\2.6.2\source\packages\fcl-extra\src\win\daemonapp.inc Code: [Select]      Repeat // Note: Working only if WaitMessage not used   CheckSynchronize;         if PeekMessage(Msg, 0, 0, 0, PM_REMOVE) then           begin           if (Msg.Message<>WM_QUIT) and (Msg.Message<>WM_ENDSESSION) then             begin // Note: Not working (No message sent) //            if (Msg.Message=WM_NULL) then //              CheckSynchronize //            else               begin               TranslateMessage(Msg);               DispatchMessage(Msg);               end;             end           else             Terminate;           end; // Note: removing the following instructions is a very BAD idea //        if not Terminated then //          WaitMessage; My conclusion is that currently, no windows message is sent in this case (if I've correctly guessed about the Synchronize implementation). And that CheckSynchronize is not called (anyway, even if present it won't be called if no message is sent, as the loop is stopped at WaitMessage). Once again, I'm not sure about this explanation, as it seems there are some other part of the code that may not need any windows message. For instance, in tthread.inc, function TThread.WaitFor: Code: [Select]...   if GetCurrentThreadID = MainThreadID then     begin       WaitHandles[0]:=FHandle;       WaitHandles[1]:=THandle(SynchronizeTimeoutEvent);       while true do         begin           case MsgWaitForMultipleObjects(2, WaitHandles, False, INFINITE, QS_SENDMESSAGE) of             WAIT_OBJECT_0:               break;             WAIT_OBJECT_0+1:               CheckSynchronize;             WAIT_OBJECT_0+2:               PeekMessage(Msg, 0, 0, 0, PM_NOREMOVE)           end;         end;     end ... I guess the main coders of all these parts may probably have a more accurate answer. ***EDIT***: My test modification for "daemonapp.inc" is not working when using a daemon application: only if you are using 'directly' the TCustomDaemon class (see this topic : http://www.lazarus.freepascal.org/index.php/topic,20652 ). I guess another windows message loop is used within a daemon application (don't know which one). ---------------------------------------------------------------------- halmariane · 2013-06-12 21:05 Hi CrisF: I don't know at this moment what's wrong. Seems that there is some stuff unimplemented in TDaemonApplication. I knew this problem long time ago. Regards ---------------------------------------------------------------------- ttomas · 2015-07-09 11:29 Any workaround about this bug? I finish my project as application where several threads are create and use Synchronize to set something to main thread. Everything works OK. Now I convert my application to Windows service (TDaemon) and hit this problem. Synchronize is not executed and code after is not executed. Code: [Select]TSomeThread.Someproc; begin     ...     Synchronize(@SetDBEvents);   // SetDBEvents is not executed     Log.Log('ReceiveRetReplication After Synchronize OK',5);   // This code is never executed     ... end; Any workaround how to signal mainthread (TDaemon) to execute some code in mainthread from TSomeThread? This bug is still open http://bugs.freepascal.org/view.php?id=24511 FPC 3.1.1 SVN Revision 48878/Win32/64 ---------------------------------------------------------------------- ttomas · 2015-07-09 11:46 Can I use SendMessage/PostMessage to TDaemon? Where is TDaemon.Handle? ---------------------------------------------------------------------- eny · 2015-07-09 13:03 Quote from: ttomas on July 09, 2015, 01:29:39 pm