Callback invocations

The connection thread thread is completely asynchronous. This means that uninstalling or replacing an existing callback does not guarantee that the existing callback gets removed, and is no longer in effect, cannot be called again. It's possible that the connection thread is in the middle of running the existing callback. The replacement or the uninstallation takes effect only when the execution thread processes the internal message to uninstall the callback, or install a replacement callback.

Callbacks get wrapped into a reference-counted object, which exists as long as the callback remains active. This means that the application's callbacks should safely capture anything they need by value (subject to restrictions on creating circular references). LibCXX's reference-counted objects (which are, incidentally, are used to build the LibCXX Widget Toolkit itself) are an excellent suggestion. The callback and the main application coordinate their mutual dependency through some reference-counted object, and the underlying framework handles the cleanup easily:

main_window->on_delete([close_flag]
    (ONLY IN_THREAD,
     const x::w::busy &ignore)
     {
         close_flag->close();
     });

This examples captures the close_flag object, which is a reference-counted object. A reference to the lambda itself gets stored internally, in the main_window, keeping the captured reference. The main application has another reference on the close_flag object, and responds by leaving main_window's scope, which destroys this object, that represents the application's main window.

This closes the window and destroys the object, together with its on_delete callback, and its captured object reference, and the application's second reference to the same object goes out of scope as well.

It is immaterial which reference to the close_flag goes out of scope first and last. Whichever reference goes out of scope last, the close_flag object gets destroyed, deleting all the memory associated with it.