All Manuals > CAPI User Guide and Reference Manual > 4 General Considerations

4.1 The correct thread for CAPI operations

All operations on displayed CAPI elements need to be in the thread (that is, the mp:process) that runs their interface. On some platforms, display and contain make a new thread. On Cocoa, all interfaces run in a single thread.

Specifying an owner (using the keyword :owner) in a dialog, for example by calling display-dialog or popup-confirmer, is also "an operation" on the owner. See 10.4 Dialog Owners for discussion of dialog owners.

In most cases this issue does not arise, because CAPI callbacks are run in the correct thread. However, if your code needs to communicate with a CAPI window from a random thread, it should use execute-with-interface, execute-with-interface-if-alive, apply-in-pane-process or apply-in-pane-process-if-alive to send the function to the correct thread.

This is why the brief interactive examples in this manual generally use execute-with-interface or apply-in-pane-process when modifying a displayed CAPI element. In contrast, the demo example in 11.4 Connecting an interface to an application is modified only by callbacks which run in the demo interface's own thread, and so there is no need to use execute-with-interface or apply-in-pane-process.

Threads started by CAPI process events in the "standard" way, that is they call mp:general-handle-event on objects that are sent to them by mp:process-send. In particular, if you want to "schedule" an event to happen in the current after the current callback returns, you can use mp:current-process-send. For example, if the display-callback of an output-pane sometimes needs to start another interface, it would be a bad idea to do this inside the display-callback, so instead of:

(capi:display new-interface)

you can use:

(mp:current-process-send `(capi:display ,new-interface))

which will cause it to happen later.

On systems other than Cocoa, when you run something that is lengthy inside a CAPI process, you can process events in a similar way to the way CAPI processes them by calling process-pending-messages, which processes all pending events and returns. However that may not always work well, because the processing of the event can do arbitrary things, so you should always consider running the lengthy computation in another process.

If your code needs to cause visible updates whilst continuing to do further computation, see 7.5.1 Updating windows in real time.

CAPI User Guide and Reference Manual (Macintosh version) - 01 Dec 2021 19:31:17