[fpc-pascal] PostMessage() from a thread (in a thread save manner)
Vinzent Höfler
JeLlyFish.software at gmx.net
Mon Oct 20 18:35:11 CEST 2008
Graeme Geldenhuys wrote:
> Some developers prefer to pass in a GUI component to a thread
> instance, so the thread knows what widget to update. Other users
> prefer to post a "gui update" message to the application event queue.
>
> I'm very new to threads and might know just enough to make in
> dangerous. :-) In fpGUI the application's "custom" event queue is a
> linked-list structure. If threads post messages to that queue, I
> obviously need to make the queue manipulation code thread safe.
>
> fpgApplication is a global singleton of the TfpgApplication class.
> fpgPostMessage() is a stand-alone function (not a member of
> TfpgApplication class). To make fpgPostMessage() thread save, I
> instantiated a TCriticalSection instance in the TfpgApplication class
> - in the constructor. I added two member functions .Lock and .Unlock
> which calls FCritSect.Enter and FCritSect.Leave respectively. In
> fpgPostMessage, I call fpgApplication.Lock, then manipulate the
> message queue and then call fpgApplication.Unlock.
>
> Is this the correct way to make my event queue thread save?
Yes and no. Allocating the message from the queue might be thread safe
now, but I strongly suspect that other threads are trying to do
something with the queue (like evaluating or removing messages).
> fpgApplication.Lock; // Enter the critical section
> try
> p := fpgAllocateMessage;
> if p <> nil then
> begin
> p^.MsgCode := MsgCode;
> p^.Sender := Sender;
> p^.Dest := Dest;
> p^.Params := aparams;
> end
> else
> DebugLn('THE MESSAGE QUEUE IS FULL.');
> finally
> fpgApplication.Unlock; // leave the critical section
> end;
So this piece of code is probably not enough to make the queue thread
safe. IMO it would be best to encapsulate any thread-safety inside the
queue class itself, instead of sprinkling "fpgApplication.{Un}Lock" all
over the source. (I know, this can be inefficient, but when having the
choice between "efficient" or "correct", I'd rather go for "correct".)
Vinzent.
More information about the fpc-pascal
mailing list