This is a draft to implement EGL_EXT_display_alloc in libglvnd.
Most of this involves reworking the hashtable that keeps track of EGLDisplays, and updating things so that it can cope with displays being modified and destroyed.
To avoid problems where one thread might try to destroy an EGLDisplay while another thread is using it, the
__EGLdisplayInfo struct now has a refcount. The mutex for the display hashtable is also used to protect the refcount.
Anything that holds on to a pointer to a
__EGLdisplayInfo either has to increment the refcount or it needs to hold the mutex for the display hashtable (since nothing else can drop the refcount to zero without holding the mutex). If all it needs to do is look up a vendor for an EGLDisplay (which is most cases), then it can still take a shared lock.
There's also counters for the number of times an EGLDisplay has been initialized and how many threads have it as their current display, so that it knows when it's safe to destroy an EGLDisplay. As a side effect of that, libglvnd now implements most of EGL_KHR_display_reference internally.
As currently implemented, a vendor library does have to have matching bookkeeping for current and init counts as libglvnd. In theory, libglvnd could handle all of that internally, and then defer calling the vendor's
eglDestroyDisplayEXT call until the EGLDisplay is ready to be deleted. However, that might happen during thread termination if the EGLDisplay is already terminated and marked for deletion, and only current on that thread. In that case, the vendor's TLS destructor might have already run.
Also note that with the last change (releasing the display hashtable lock for most of eglMakeCurrent), I haven't worked through all of the various permutations of multiple EGLDisplays and multiple vendors yet, so I'm not quite confident that everything there works.