Re: [Lazarus] TThread.Synchronize
On 25.10.2016 14:07, LacaK via Lazarus wrote: Yes this can happen. MyForm.MyMethod is called also from event handler and also is used in Synchronize(@MyForm.MyMethod) How can this happen/play role? I suppose by "event handler" you mean a GUI event (Mouse, Keyboard, ...) Such events are serviced by the Queue as well and hence run in the same Thread ("MainThread" as the synchronized methods. So there can't be a mutual interrupt. The whole point with the Event programming paradigm is to do "run to completion" events. -Michael -- ___ Lazarus mailing list Lazarus@lists.lazarus-ide.org http://lists.lazarus-ide.org/listinfo/lazarus
Re: [Lazarus] TThread.Synchronize
On Wed, 26 Oct 2016 20:23:11 +0200 Sascha Hestermann via Lazarus wrote: > Am 26.10.2016 um 12:02 schrieb LacaK via Lazarus: > > Btw. when TTimer is executing OnTimer method, which does not finishes > > until next Interval is elapsed, is again called OnTimer ? Or next > > OnTimer is performed only when prior OnTimer finished ? The next time event is set when the timer event has finished. That's why it is not an exact interval timer. > Afaik TTimer periodically sends a message to the event queue (at least > on Windows) and the OnTimer method is called once this message is > processed. So unless you call ProcessMessages within your OnTimer method > it won't be called again before it's finished. Yes. Mattias -- ___ Lazarus mailing list Lazarus@lists.lazarus-ide.org http://lists.lazarus-ide.org/listinfo/lazarus
Re: [Lazarus] TThread.Synchronize
Am 26.10.2016 um 12:02 schrieb LacaK via Lazarus: > Btw. when TTimer is executing OnTimer method, which does not finishes > until next Interval is elapsed, is again called OnTimer ? Or next > OnTimer is performed only when prior OnTimer finished ? Afaik TTimer periodically sends a message to the event queue (at least on Windows) and the OnTimer method is called once this message is processed. So unless you call ProcessMessages within your OnTimer method it won't be called again before it's finished. -- ___ Lazarus mailing list Lazarus@lists.lazarus-ide.org http://lists.lazarus-ide.org/listinfo/lazarus
Re: [Lazarus] TThread.Synchronize
On 26.10.2016 12:02, LacaK via Lazarus wrote: you just could use TTimer. probably yes. I do not remember why I have used thread for it. May be I do not wanted dependency on ExtCtrls ... Btw. when TTimer is executing OnTimer method, which does not finishes until next Interval is elapsed, is again called OnTimer ? Or next OnTimer is performed only when prior OnTimer finished ? Using a "Worker" Thread makes sense when - long winding stuff (calculations, file search, database, ...) are done in the Thread and the GUI is supposed to go on working during that time - you want to take advantage of multiple cores working in parallel (e.g. for number crunching) - you want to wait for external events in a blocking OS Call (e.g. Socket). I would avoid using Threads if not decently justified, as a lot complexity is added. -Michael -- ___ Lazarus mailing list Lazarus@lists.lazarus-ide.org http://lists.lazarus-ide.org/listinfo/lazarus
Re: [Lazarus] TThread.Synchronize
Dňa 26.10.2016 o 11:17 Michael Schnell via Lazarus napísal(a): On 26.10.2016 07:57, LacaK via Lazarus wrote: procedure TRefreshFileListThread.Execute; begin while not Terminated do begin Synchronize(@MyForm.UpdateFileList); // UpdateFileList is method which clears listbox and then adds files in given shared folder Sleep(1); end; This only makes sense if the actual file list generation (all but the GUI update) is done in not shown code in the thread before Synchonize is called. no. thread code is all what you see above. my intention was use thread only for periodical refresh of list Otherwise you just could use TTimer. probably yes. I do not remember why I have used thread for it. May be I do not wanted dependency on ExtCtrls ... Btw. when TTimer is executing OnTimer method, which does not finishes until next Interval is elapsed, is again called OnTimer ? Or next OnTimer is performed only when prior OnTimer finished ? -Laco. -- ___ Lazarus mailing list Lazarus@lists.lazarus-ide.org http://lists.lazarus-ide.org/listinfo/lazarus
Re: [Lazarus] TThread.Synchronize
On 26.10.2016 07:57, LacaK via Lazarus wrote: procedure TRefreshFileListThread.Execute; begin while not Terminated do begin Synchronize(@MyForm.UpdateFileList); // UpdateFileList is method which clears listbox and then adds files in given shared folder Sleep(1); end; This only makes sense if the actual file list generation (all but the GUI update) is done in not shown code in the thread before Synchonize is called. Otherwise you just could use TTimer. Is this done that way? -Michael -- ___ Lazarus mailing list Lazarus@lists.lazarus-ide.org http://lists.lazarus-ide.org/listinfo/lazarus
Re: [Lazarus] TThread.Synchronize
Big Thanks to all. Now I understand what is happening ... probably I wil use critical section to block access from thread when code in main thread is performed ... -Laco. ShowModal() for a modal form will call it. [...] I did test in Delphi and Delphi seems also perform synchronize upon ShowModal Yes. Nowhere is it stated or guaranteed that synchronisation cannot happen in a GUI event handler. But cann't happen if nobody calls ProcessMessages or CheckSynchronize explicitly. So if user code is executed in event handler then this execution cann't be interrupted by thread waiting for "synchronization" Yes. Unless you call something that does call HandleMessages/ProcessMessages or CheckSynchronize. Any code at any time can call the GUI message loop. A modal form is just one instance. ModalForm is IMO one example but may be alone in LCL ... as there are no more controls which do same, does not ? The dialogs like TOpenDialog and ShowMessage call it. Another example is reading the Clipboard on gtk and retrieving files in TShellTreeView. Mattias -- ___ Lazarus mailing list Lazarus@lists.lazarus-ide.org http://lists.lazarus-ide.org/listinfo/lazarus
Re: [Lazarus] TThread.Synchronize
On Wed, 26 Oct 2016 09:49:44 +0200 LacaK via Lazarus wrote: > >>> ShowModal() for a modal form will call it. >[...] > I did test in Delphi and Delphi seems also perform synchronize upon > ShowModal Yes. > > Nowhere is it stated or guaranteed that synchronisation cannot happen > > in a GUI event > > handler. > > But cann't happen if nobody calls ProcessMessages or CheckSynchronize > explicitly. > So if user code is executed in event handler then this execution cann't > be interrupted by thread waiting for "synchronization" Yes. Unless you call something that does call HandleMessages/ProcessMessages or CheckSynchronize. > > Any code at any time can call the GUI message loop. A modal form is > > just one instance. > > ModalForm is IMO one example but may be alone in LCL ... as there are no > more controls which do same, does not ? The dialogs like TOpenDialog and ShowMessage call it. Another example is reading the Clipboard on gtk and retrieving files in TShellTreeView. Mattias -- ___ Lazarus mailing list Lazarus@lists.lazarus-ide.org http://lists.lazarus-ide.org/listinfo/lazarus
Re: [Lazarus] TThread.Synchronize
ShowModal() for a modal form will call it. Ah really? It happens in my application! Then that is your problem. :-))) But is it correct behavior ? IMO it is against thread safety, which should Synchronize guarantee! The two issues are completely unrelated. The current behaviour is correct. I did test in Delphi and Delphi seems also perform synchronize upon ShowModal Nowhere is it stated or guaranteed that synchronisation cannot happen in a GUI event handler. But cann't happen if nobody calls ProcessMessages or CheckSynchronize explicitly. So if user code is executed in event handler then this execution cann't be interrupted by thread waiting for "synchronization" Any code at any time can call the GUI message loop. A modal form is just one instance. ModalForm is IMO one example but may be alone in LCL ... as there are no more controls which do same, does not ? So in my mind it is very specific case, which should be documented. Of course there can be any user defined control which will do same ... Your code must be able to deal with this. Yes, thanks -Laco. -- ___ Lazarus mailing list Lazarus@lists.lazarus-ide.org http://lists.lazarus-ide.org/listinfo/lazarus
Re: [Lazarus] TThread.Synchronize
On Wed, 26 Oct 2016, LacaK via Lazarus wrote: Check for Application.ProcessMessages and CheckSynchronize calls. These process synchronize queue, if I am not mistaken. I do not call CheckSynchronize nor ProcessMessages in my application. So only any LCL component or widget set can call it in background ? ShowModal() for a modal form will call it. Ah really? It happens in my application! Then that is your problem. But is it correct behavior ? IMO it is against thread safety, which should Synchronize guarantee! The two issues are completely unrelated. The current behaviour is correct. Nowhere is it stated or guaranteed that synchronisation cannot happen in a GUI event handler. Any code at any time can call the GUI message loop. A modal form is just one instance. Your code must be able to deal with this. Michael. -- ___ Lazarus mailing list Lazarus@lists.lazarus-ide.org http://lists.lazarus-ide.org/listinfo/lazarus
Re: [Lazarus] TThread.Synchronize
Check for Application.ProcessMessages and CheckSynchronize calls. These process synchronize queue, if I am not mistaken. I do not call CheckSynchronize nor ProcessMessages in my application. So only any LCL component or widget set can call it in background ? ShowModal() for a modal form will call it. Ah really? It happens in my application! Basicaly I have one form MyForm with one background thread, which every 10 sec. checks for files in shared folder and adds them to listbox visible to user: procedure TRefreshFileListThread.Execute; begin while not Terminated do begin Synchronize(@MyForm.UpdateFileList); // UpdateFileList is method which clears listbox and then adds files in given shared folder Sleep(1); end; When new file is shown then user can click on button, which imports data from this file: Before import is shown another form with question about "Do you want really import file XYZ ?" Do you say, that when this "question form" is shown it can release call to MyForm.UpdateFileList ? Now I did quick test and it seems, that it is so! But is it correct behavior ? IMO it is against thread safety, which should Synchronize guarantee! While "main thread" is executing others threads should wait in queue ... if not fixable, then can it be documented?, because this is exception which is not intuitive -Laco. -- ___ Lazarus mailing list Lazarus@lists.lazarus-ide.org http://lists.lazarus-ide.org/listinfo/lazarus
Re: [Lazarus] TThread.Synchronize
On Tue, 25 Oct 2016 15:02:06 +0200 LacaK via Lazarus wrote: > >> I do not call CheckSynchronize nor ProcessMessages in my application. > >> So only any LCL component or widget set can call it in background ? > > > > It should be easy for you to set a breakpoint into MyForm.MyMethod and > > check the call stack. > > > But error (AV) happens only in production and only sometimes. > Is there any way how to write call stack into file ? You can try GetStackTrace(true) and save it string to a file. It must be called from main thread. Mattias -- ___ Lazarus mailing list Lazarus@lists.lazarus-ide.org http://lists.lazarus-ide.org/listinfo/lazarus
Re: [Lazarus] TThread.Synchronize
On Tue, 25 Oct 2016 13:37:03 +0200 Michael Schnell via Lazarus wrote: > > If you don't call CheckSynchronize within MyForm.MyMethod then yes. > IMHO the (hardly documented) CheckSynchronize should not be called > directly by an application that uses a Widget Type that features an > Event Queue. Here the user should do "Application.ProcessMessages", that > is decently documented. CheckSynchronize checks the FPC thread queue. Application.ProcessMessages calls CheckSynchronize and checks the LCL event queues. It is not forbidden to call CheckSynchronize in a LCL application. Mattias -- ___ Lazarus mailing list Lazarus@lists.lazarus-ide.org http://lists.lazarus-ide.org/listinfo/lazarus
Re: [Lazarus] TThread.Synchronize
I do not call CheckSynchronize nor ProcessMessages in my application. So only any LCL component or widget set can call it in background ? It should be easy for you to set a breakpoint into MyForm.MyMethod and check the call stack. But error (AV) happens only in production and only sometimes. Is there any way how to write call stack into file ? TIA -Laco. -- ___ Lazarus mailing list Lazarus@lists.lazarus-ide.org http://lists.lazarus-ide.org/listinfo/lazarus
Re: [Lazarus] TThread.Synchronize
On Tue, 25 Oct 2016, LacaK via Lazarus wrote: Check for Application.ProcessMessages and CheckSynchronize calls. These process synchronize queue, if I am not mistaken. I do not call CheckSynchronize nor ProcessMessages in my application. So only any LCL component or widget set can call it in background ? ShowModal() for a modal form will call it. Michael. -- ___ Lazarus mailing list Lazarus@lists.lazarus-ide.org http://lists.lazarus-ide.org/listinfo/lazarus
Re: [Lazarus] TThread.Synchronize
On 25.10.2016 14:12, LacaK via Lazarus wrote: I do not call CheckSynchronize nor ProcessMessages in my application. So only any LCL component or widget set can call it in background ? It should be easy for you to set a breakpoint into MyForm.MyMethod and check the call stack. Ondrej -- ___ Lazarus mailing list Lazarus@lists.lazarus-ide.org http://lists.lazarus-ide.org/listinfo/lazarus
Re: [Lazarus] TThread.Synchronize
Check for Application.ProcessMessages and CheckSynchronize calls. These process synchronize queue, if I am not mistaken. I do not call CheckSynchronize nor ProcessMessages in my application. So only any LCL component or widget set can call it in background ? From Delphi doc: "Synchronize causes the call specified by AMethod to be executed using the main thread, thereby avoiding multithread conflicts. If you are unsure whether a method call is thread-safe, call it from within the Synchronize method to ensure that it executes in the main thread. Execution of the current thread is suspended while the method executes in the main thread. " Looking from where is called CheckSynchronize: - TWin32WidgetSet.AppProcessMessages - win32callback.inc: case Msg of WM_NULL: if (Window = Win32WidgetSet.AppHandle) then begin CheckSynchronize; ... Cann't something send WM_NULL to application which can as reaction run sheduled thread ? WM_NULL sends HandleWakeMainThread() which is handler stored in variable WakeMainThread Messages in win32callback are processed by "main thread" only, so execution cann't happen while form method is executed ? -Laco. -Laco. -- ___ Lazarus mailing list Lazarus@lists.lazarus-ide.org http://lists.lazarus-ide.org/listinfo/lazarus
Re: [Lazarus] TThread.Synchronize
Check for Application.ProcessMessages and CheckSynchronize calls. These process synchronize queue, if I am not mistaken. I do not call CheckSynchronize nor ProcessMessages in my application. So only any LCL component or widget set can call it in background ? -Laco. -- ___ Lazarus mailing list Lazarus@lists.lazarus-ide.org http://lists.lazarus-ide.org/listinfo/lazarus
Re: [Lazarus] TThread.Synchronize
My understanding is that, Synchronize schedules execution of MyForm.MyMethod to main thread, so method is not executed until control is returned from event handler in MyForm. Right? TThread.Synchronze pushes the procedure that is given as a parameter (including it's Self pointer) to the event queue and then the Therad that called TThread.Synchronize is stalled. ok Some time later the main (GUI) thread will execute the scheduled procedure. When this call returns, the thread that called TThread.Synchronize is activated. ok but what is relation between "main thread" and this "sheduled procedure" ? Can "sheduled procedure" jump into execution while main thread is still executing prior called form method ? There also is TThread.Queue that works identically, only without stalling the thread. yes, but I do not want this But in my case happens, that method is executed while execution of event handler does not finished yet ... is it expected behavior ? What is "that method"? If same is called by the thread after TThread.Synchronize, IMHO this can't be correct. Yes this can happen. MyForm.MyMethod is called also from event handler and also is used in Synchronize(@MyForm.MyMethod) How can this happen/play role? I have suspection that somewhere in Win32 widgetset is called CheckSynchronize as reaction on some message or so, which releases execution of MyForm.MyMethod ... but it is inappropriate, does not ? -Laco. -- ___ Lazarus mailing list Lazarus@lists.lazarus-ide.org http://lists.lazarus-ide.org/listinfo/lazarus
Re: [Lazarus] TThread.Synchronize
If you don't call CheckSynchronize within MyForm.MyMethod then yes. IMHO the (hardly documented) CheckSynchronize should not be called directly by an application that uses a Widget Type that features an Event Queue. Here the user should do "Application.ProcessMessages", that is decently documented. -Michael -- ___ Lazarus mailing list Lazarus@lists.lazarus-ide.org http://lists.lazarus-ide.org/listinfo/lazarus
Re: [Lazarus] TThread.Synchronize
On 25.10.2016 13:21, LacaK via Lazarus wrote: My understanding is that, Synchronize schedules execution of MyForm.MyMethod to main thread, so method is not executed until control is returned from event handler in MyForm. Right? TThread.Synchronze pushes the procedure that is given as a parameter (including it's Self pointer) to the event queue and then the Therad that called TThread.Synchronize is stalled. Some time later the main (GUI) thread will execute the scheduled procedure. When this call returns, the thread that called TThread.Synchronize is activated. There also is TThread.Queue that works identically, only without stalling the thread. But in my case happens, that method is executed while execution of event handler does not finished yet ... is it expected behavior ? What is "that method"? If same is called by the thread after TThread.Synchronize, IMHO this can't be correct. -Michael -- ___ Lazarus mailing list Lazarus@lists.lazarus-ide.org http://lists.lazarus-ide.org/listinfo/lazarus
Re: [Lazarus] TThread.Synchronize
On 25.10.2016 13:21, LacaK via Lazarus wrote: I have form on which is button. When user clicks button OnClick event handler is called (it is method of form). Processing of this method takes some time say 1 minute. In the background is operating another thread which every 10 seconds calls Synchronize(@MyForm.MyMethod). My understanding is that, Synchronize schedules execution of MyForm.MyMethod to main thread, so method is not executed until control is returned from event handler in MyForm. Right? If you don't call CheckSynchronize within MyForm.MyMethod then yes. But in my case happens, that method is executed while execution of event handler does not finished yet ... is it expected behavior ? If not is there any workaroud which enables me to hold thread until event handler finishes ? Check for Application.ProcessMessages and CheckSynchronize calls. These process synchronize queue, if I am not mistaken. Ondrej -- ___ Lazarus mailing list Lazarus@lists.lazarus-ide.org http://lists.lazarus-ide.org/listinfo/lazarus