egl: Set atexit() handler during initialization

This ensure that the default handlers enumerated in
eglGlobal will be called.  Historically the atexit() would
be set when adding a new handler, but as the code moved on
the handlers were included by default and the function
that added them is not being called anymore.

This fixes memory leaks like

```
==37635== 144 bytes in 1 blocks are still reachable in loss record 2,416 of 2,428
==37635==    at 0x48463F3: calloc (vg_replace_malloc.c:1675)
==37635==    by 0x7D13686: ??? (in /usr/lib64/libdrm.so.2.125.0)
==37635==    by 0x7D13A13: ??? (in /usr/lib64/libdrm.so.2.125.0)
==37635==    by 0x7D18310: drmGetDevices2 (in /usr/lib64/libdrm.so.2.125.0)
==37635==    by 0x4FFC411: _eglDeviceRefreshList (egldevice.c:431)
==37635==    by 0x4FF079A: eglInitialize (eglapi.c:672)
==37635==    by 0x40078F: main (main.c:75)
```

and

```
==37664== 2,680 bytes in 1 blocks are still reachable in loss record 2,423 of 2,428
==37664==    at 0x48463F3: calloc (vg_replace_malloc.c:1675)
==37664==    by 0x4FFCDF3: _eglFindDisplay (egldisplay.c:270)
==37664==    by 0x4FEED00: eglGetDisplay (eglapi.c:418)
==37664==    by 0x501464E: __eglGLVNDGetPlatformDisplay (eglglvnd.c:67)
==37664==    by 0x488170D: ??? (in /usr/lib64/libEGL.so.1.1.0)
==37664==    by 0x40075C: main (main.c:68)
```

Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Reviewed-by: Eric Engestrom <eric@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/37518>
This commit is contained in:
Caio Oliveira 2025-09-22 13:03:16 -07:00 committed by Marge Bot
parent 0f7e0f79ad
commit 8435837a5b
3 changed files with 19 additions and 7 deletions

View file

@ -670,6 +670,7 @@ eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
_EGL_FUNC_START(disp, EGL_OBJECT_DISPLAY_KHR, NULL);
_eglDeviceRefreshList();
_eglRegisterAtExit();
if (!disp)
RETURN_EGL_ERROR(NULL, EGL_BAD_DISPLAY, EGL_FALSE);

View file

@ -115,19 +115,27 @@ _eglAtExit(void)
_eglGlobal.AtExitCalls[i]();
}
void
_eglRegisterAtExit(void)
{
static EGLBoolean registered = EGL_FALSE;
simple_mtx_lock(_eglGlobal.Mutex);
if (!registered) {
atexit(_eglAtExit);
registered = EGL_TRUE;
}
simple_mtx_unlock(_eglGlobal.Mutex);
}
void
_eglAddAtExitCall(void (*func)(void))
{
if (func) {
static EGLBoolean registered = EGL_FALSE;
simple_mtx_lock(_eglGlobal.Mutex);
if (!registered) {
atexit(_eglAtExit);
registered = EGL_TRUE;
}
assert(_eglGlobal.NumAtExitCalls < ARRAY_SIZE(_eglGlobal.AtExitCalls));
_eglGlobal.AtExitCalls[_eglGlobal.NumAtExitCalls++] = func;

View file

@ -74,6 +74,9 @@ struct _egl_global {
extern struct _egl_global _eglGlobal;
extern void
_eglRegisterAtExit(void);
extern void
_eglAddAtExitCall(void (*func)(void));