Lockups at program terminations

There can be several reasons why an LibCXX Windows Library-using program does not properly terminate.

Problems disconnecting from the X Input Method server

LibCXX Windows Library does an orderly teardown of the connection to the XIM server when the library shuts down. For troubleshooting purposes:

x::w::skip_xim_disconnect=true

This terminates the connection with the XIM server immediately.

Circular references

LibCXX Windows Library uses smart pointers/reference counted objects to implement all display elements. A circular reference results in class instances of various LibCXX Windows Library display elements not getting destroyed correctly. This prevents the library's internal execution thread from properly shutting down. The internal execution thread does not stop until all objects that use it get destroyed.

This chapter discusses some of the common causes of circular references and how to eliminate them.

Containers hold references to all display elements in the container

A basic display element, like a button, is owned by its container (the top level main window, or an intermediate container). Taking the button element, and storing its parent container in the element's appdata field creates a circular reference.

Capturing display elements in callbacks

A callback for a display element cannot capture a reference to the display element's parent or child elements. This creates an internal circular reference.

Using weak captures is often the simplest solution.

Storing display elements in static or dynamic scope
static x::w::labelptr l;

void create_tab(const &x::w::factory &f)
{
     l=f->create_label("Hello world");
}

Unless something gets rid of this statically-scoped reference to a display element, its existence will prevent LibCXX Windows Library from properly shutting down. Good rules of thumb to follow:

  • All display elements get created in automatic scope. All examples in this tutorial create their x::w::main_windows in automatic scope, before creating all display elements but not directly storing them anywhere.

  • The remaining display elements get created, and generally not separately stored anywhere other than internally, by the library, in their containers.

  • Callbacks attached to display elements typically weakly capture any other elements they need. In limited, well defined, controlled cases, a callback captures a different display element in an unrelated hierarchy.