Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-devel / 2008-09

TThread.WaitFor causes deadlock under Linux

2 messages · 2 people ·

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Graeme Geldenhuys

Hi,

I posted the original message in the fpc-users mailing list, but after a few replies, I seem to think it's a bug in FPC. Hence I decided to post the message here as well.

-------------------[ original mail ]--------------------- I have a thread based logging framework (part of tiOPF). I created a "Log to GUI" viewer for the log framework using fpGUI toolkit. While the application runs, the cached logging to the GUI window works perfectly - no problems there. For some reason, the call to the internal TThread.WaitFor doesn't always return when the application terminates. The viewer is based on code for Delphi's VCL, which never showed this issue.

I'm not sure how to debug threads and don't have a clue as to what could cause the problem.

My application is built with FPC 2.2.3 and fpGUI toolkit, running under Ubuntu Linux 7.10 (2.6 based kernel).

Example of a successful termination:

./tutoradmin.exe -lv
TtiLogToGUI.FormClose called

> TfpgApplication.Destroy

destroying components... DONE
killing message queue
<< TfpgApplication.Destroy

> TtiLogToCacheAbs.Terminate

called .Terminate() and now calling .WaitFor()
<< TtiLogToCacheAbs.Terminate

An example, where the application doesn't terminate.

./tutoradmin.exe -lv
TtiLogToGUI.FormClose called

> TfpgApplication.Destroy

destroying components... DONE
killing message queue
<< TfpgApplication.Destroy

> TtiLogToCacheAbs.Terminate

called .Terminate() and now calling .WaitFor()

I have to press Ctrl+C to terminate the application fully.

TtiLogToCacheAbs is a abstract base class used for cached logging. It contains a TCriticalSection and a TThread.

TtiLogToGUI is a descendant of TtiLogToCacheAbs and contains the GUI Form instance (visual logging). The GUI Form is closed and destroyed before the Application or thread terminates. It's the first output line (....FormClose) shown above...

Here is the section of code which doesn't complete 100% and hangs the application when the application gets terminated.

procedure TtiLogToCacheAbs.Terminate;
begin
 writeln('>> TtiLogToCacheAbs.Terminate');
 FThrdLog.Terminate;
 writeln('   called .Terminate() and now calling .WaitFor()');
 FThrdLog.WaitFor;
 writeln('<< TtiLogToCacheAbs.Terminate');
end;

Any ideas?

---------------[ and some responses ]-------------------------

Show quoted text 16 lines
> When you call synchronize from inside of you thread, this sends a message > to > application thread with the procedure that will be used to synchronize AND > WAIT FOR a response from application thread of the execution of sync > procedure. BUT when you call Thread.WaitFor in application thread, the > application don't process any messages because it is waiting the thread > finish, and thread don't finish because it is waiting a response of > application thread of the execution of sync procedure... and you have your > aplication freeze! This is exactly what seems to be happening... I'll try your work-around and see how it goes. Thanks. Note: I have no such issues in Delphi, using the exact same threading code. So does that mean FPC has a bug in threading?

Delphi has code in its WaitFor function that prevents this deadlock from occuring. They basically wait on the SyncEvent and the handle of the thread, calling CheckSynchonize when the SyncEvent triggers.

I'm not sure if this is possible with fpc, but I'm sure there must be a solution.
-------------------------[ end ]---------------------------

What can I do to resolve this problem? I'm not very knowledable with threads so bare with me... TThread.WaitFor is not virtual, so I can't override it and try and place a CheckSynchronize call in there. What else could I try? Is this a know bug in FPC and TThread under Linux/Unix?

I have the UseCThreads define enabled, which pulls in the 'cthreads' unit in my program unit.

Regards,
- Graeme -

_______________________________________________
fpGUI - a cross-platform Free Pascal GUI toolkit
http://opensoft.homeip.net/fpgui/

Reply by email

Peter Popov
to Graeme Geldenhuys

It may not be relevant, but do you specify a timeout for the wait?

Peter

Graeme Geldenhuys wrote 123 lines
Hi, I posted the original message in the fpc-users mailing list, but after a few replies, I seem to think it's a bug in FPC. Hence I decided to post the message here as well. -------------------[ original mail ]--------------------- I have a thread based logging framework (part of tiOPF). I created a "Log to GUI" viewer for the log framework using fpGUI toolkit. While the application runs, the cached logging to the GUI window works perfectly - no problems there. For some reason, the call to the internal TThread.WaitFor doesn't always return when the application terminates. The viewer is based on code for Delphi's VCL, which never showed this issue. I'm not sure how to debug threads and don't have a clue as to what could cause the problem. My application is built with FPC 2.2.3 and fpGUI toolkit, running under Ubuntu Linux 7.10 (2.6 based kernel). Example of a successful termination: ./tutoradmin.exe -lv TtiLogToGUI.FormClose called >> TfpgApplication.Destroy destroying components... DONE killing message queue << TfpgApplication.Destroy >> TtiLogToCacheAbs.Terminate called .Terminate() and now calling .WaitFor() << TtiLogToCacheAbs.Terminate An example, where the application doesn't terminate. ./tutoradmin.exe -lv TtiLogToGUI.FormClose called >> TfpgApplication.Destroy destroying components... DONE killing message queue << TfpgApplication.Destroy >> TtiLogToCacheAbs.Terminate called .Terminate() and now calling .WaitFor() I have to press Ctrl+C to terminate the application fully. TtiLogToCacheAbs is a abstract base class used for cached logging. It contains a TCriticalSection and a TThread. TtiLogToGUI is a descendant of TtiLogToCacheAbs and contains the GUI Form instance (visual logging). The GUI Form is closed and destroyed before the Application or thread terminates. It's the first output line (....FormClose) shown above... Here is the section of code which doesn't complete 100% and hangs the application when the application gets terminated. procedure TtiLogToCacheAbs.Terminate; begin writeln('>> TtiLogToCacheAbs.Terminate'); FThrdLog.Terminate; writeln(' called .Terminate() and now calling .WaitFor()'); FThrdLog.WaitFor; writeln('<< TtiLogToCacheAbs.Terminate'); end; Any ideas? ---------------[ and some responses ]------------------------- >> When you call synchronize from inside of you thread, this sends a >> message >> to >> application thread with the procedure that will be used to synchronize >> AND >> WAIT FOR a response from application thread of the execution of sync >> procedure. BUT when you call Thread.WaitFor in application thread, the >> application don't process any messages because it is waiting the thread >> finish, and thread don't finish because it is waiting a response of >> application thread of the execution of sync procedure... and you have >> your >> aplication freeze! > > This is exactly what seems to be happening... I'll try your > work-around and see how it goes. Thanks. > > Note: > I have no such issues in Delphi, using the exact same threading code. > So does that mean FPC has a bug in threading? Delphi has code in its WaitFor function that prevents this deadlock from occuring. They basically wait on the SyncEvent and the handle of the thread, calling CheckSynchonize when the SyncEvent triggers. I'm not sure if this is possible with fpc, but I'm sure there must be a solution. -------------------------[ end ]--------------------------- What can I do to resolve this problem? I'm not very knowledable with threads so bare with me... TThread.WaitFor is not virtual, so I can't override it and try and place a CheckSynchronize call in there. What else could I try? Is this a know bug in FPC and TThread under Linux/Unix? I have the UseCThreads define enabled, which pulls in the 'cthreads' unit in my program unit. Regards, - Graeme - _______________________________________________ fpGUI - a cross-platform Free Pascal GUI toolkit http://opensoft.homeip.net/fpgui/ _______________________________________________ fpc-devel maillist - http://lists.freepascal.org/mailman/listinfo/fpc-devel

Reply by email