Am 08.10.2010 14:03, schrieb Graeme Geldenhuys:
if IsMultiThreaded then begin writeln('******'); CheckSynchronized(); end;
[snip]
procedure TBarThread.Execute; begin FFinished := False; // work-around variable while not Terminated do begin Synchronize(@UpdateProgressBar); end; FFinished := True; // work-around variable end;
[snip]
procedure TMainForm.ButtonClicked(Sender: TObject); begin ProgressBar1.Position := ProgressBar1.Min; if not Assigned(FThread) then begin writeln('program: creating thread...'); FThread := TBarThread.Create(True); FThread.ProgressBar := ProgressBar1; end; writeln('program: starting the thread...'); FThread.Start; writeln('program: waiting for thread...'); FThread.WaitFor; // Can use this, it blocks the main event loop // my work-around while not FThread.Finished do begin sleep(100); fpgApplication.ProcessMessages; end; writeln('program: thread is finished!'); Label1.Text := 'Thread is done'; FreeAndNil(FThread); end;
Looking again at your example code explains very clearly what happens (I assume the CheckSynchronize call is in your ProcessMessages method):
In the thread you call Synchronize which will stop the thread until the main thread has found time to process all queued Synchronize messages (by calling CheckSynchronize). Read again: the thread is SUSPENDED, it's in a waiting state.
Now you call .WaitFor during an event handler. So you wait until the thread is finished.
There is the problem: The main thread is waiting for the second thread to finish and the second thread is waiting for the main thread to find time to process its synchronized message. This is a classical DEADLOCK.
The "workaround" is not really a workaround, but more a "clean solution" (there are other ones that others already mentioned like running an OnTerminate-event, which is supported on Delphi as well).
And it doesn't appear on Windows, because WaitFor uses MsgWaitForMultipleObjects which waits for either the thread's handle, the synchronize timeout (in which case CheckSynchronize is run) or a message that is send from Windows' message system (which is then processed). So a Windows GUI won't hang (Sergei has mentioned this on the Lazarus list).
So from the following statement:
So what is wrong? Is it the TThread.WaitFor implementation that is flawed? Is it X11 that is flawed, or just GUI toolkit developers that don't know how to code (thought I doubt it's the latter).
I'll choose the third option. ;P (please don't be offended) Regards, Sven _______________________________________________ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal