Handles

Handles abstract the pointer over memory or network boundaries.

thingbuilder_t tb;
tb.version = sizeof(thingbuilder_t);
tb_set_port(&tb, 8080);
int t = thing_create(&tb);
/* do things  */
thing_destroy(t);

This completely separates the client from details of the object it is working with. Sometimes this has been used by C++ libraries that completely hide all object semantics (which are compiler-specific) and expose a handle interface via a C ABI (which is stable.)

This abstraction is extensively used by OpenGL and Khronos ABIs.

Multi-threading

The exact value of a handle is undefined. However there can be issues where multiple threads may be taking and returning handles. This can create contention managing the handles.

Our Machinery suggested a method where the total handle pool is split some number of ways such as one split per CPU. Each processor then pulls from it's specific pool. That way the majority of handle activity stays to that processor.

Similar tricks have been used by many memory allocation systems; pages set aside for particular threads so contention only happens where specific handoffs have to occur.