Search code examples
delphiasynchronouslazaruspostmessagefpc

Execute code in the context of the main thread (Lazarus)


I have to execute some code in the context of the main thread. I am using Lazarus + FPC. I receive an event from a thread inside a DLL (shared library if on linux) and my callback function gets called. Note that this function is not a member of any class but a standalone traditional function with a "cdecl" directive attached.

I have to triger a coresponding property event handler for each such message I receive. And these events have to be passed on in the context of the main thread. I know of two such solutions:

  1. PostMessage
  2. Application.QueueAsyncCall

The first one is ok, but it requires a window handle. And since this is a library code no handle is available. AllocateHWND is not an option since it is not cross platform. I know I can create a dummy form but this is a very bad solution

The second works ok, but I have a problem, that the call is not processed until I move a mouse inside application for instance. Maybe I am doing something wrong I don't know. I is just like my call is being processed only when message processing kicks in. But this can be a long wait apparently.

So I want to know what is the best solution here (probably QueueAsyncCall) and how I can be sure that my message (call) will be processed in acceptable timeframe?


Solution

  • You can not be 100% sure, just like you can't in any non-realtime system. If the mainthread hangs, it won't check for messages or other events in the main loop. This is normal.

    The only thing you can do is to avoid doing stuff in the mainthread that can take a long time. It's the trick of the trade to exactly judge what is necessary and what is not. Some realtime oriented people move all filesystem access to threads, and keep the GUI strictly for UI, just because if an user configures a path on a network share for this or the other, a problem with the share can easily cause a long timeout wait, of minutes even.

    If I look at application.queueasynccall, I see no threadsafe processing (no locking or locked queues), so that one is out.

    I know postmessage is emulated by Lazarus to some degree on non Windows, and I checked the implementation and it does have lock, so I assume it is multithreading safe.