Make colormap private interfaces thread safe.

Protect access to the dpy structure by a display lock, so that these can
be called outside of a global display lock.

That allows the XCMS colormap functions to be thread safe without having
the whole functions within a display lock, to avoid deadlocks.

Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
See-also: https://gitlab.freedesktop.org/xorg/lib/libx11/-/issues/215
See-also: https://gitlab.freedesktop.org/xorg/lib/libx11/-/issues/94
Reviewed-by: Adam Jackson <ajax@redhat.com>
Part-of: <https://gitlab.freedesktop.org/xorg/lib/libx11/-/merge_requests/254>
This commit is contained in:
Olivier Fourdan 2024-06-07 09:05:55 +02:00 committed by Marge Bot
parent 739fce4c12
commit 1472048b7a

View file

@ -87,12 +87,17 @@ CmapRecForColormap(
_XAsyncHandler async;
_XAsyncErrorState async_state;
LockDisplay(dpy);
for (pRec = (XcmsCmapRec *)dpy->cms.clientCmaps; pRec != NULL;
pRec = pRec->pNext) {
if (pRec->cmapID == cmap) {
UnlockDisplay(dpy);
SyncHandle();
return(pRec);
}
}
UnlockDisplay(dpy);
SyncHandle();
/*
* Can't find an XcmsCmapRec associated with cmap in our records.
@ -258,9 +263,12 @@ _XcmsAddCmapRec(
pNew->dpy = dpy;
pNew->windowID = windowID;
pNew->visual = visual;
LockDisplay(dpy);
pNew->pNext = (XcmsCmapRec *)dpy->cms.clientCmaps;
dpy->cms.clientCmaps = (XPointer)pNew;
dpy->free_funcs->clientCmaps = _XcmsFreeClientCmaps;
UnlockDisplay(dpy);
SyncHandle();
/*
* Note, we don't create the XcmsCCC for pNew->ccc here because
@ -342,6 +350,7 @@ _XcmsDeleteCmapRec(
}
/* search for it in the list */
LockDisplay(dpy);
pPrevPtr = (XcmsCmapRec **)&dpy->cms.clientCmaps;
while ((pRec = *pPrevPtr) && (pRec->cmapID != cmap)) {
pPrevPtr = &pRec->pNext;
@ -354,6 +363,8 @@ _XcmsDeleteCmapRec(
*pPrevPtr = pRec->pNext;
Xfree(pRec);
}
UnlockDisplay(dpy);
SyncHandle();
}
@ -378,6 +389,7 @@ _XcmsFreeClientCmaps(
{
XcmsCmapRec *pRecNext, *pRecFree;
LockDisplay(dpy);
pRecNext = (XcmsCmapRec *)dpy->cms.clientCmaps;
while (pRecNext != NULL) {
pRecFree = pRecNext;
@ -390,6 +402,8 @@ _XcmsFreeClientCmaps(
Xfree(pRecFree);
}
dpy->cms.clientCmaps = (XPointer)NULL;
UnlockDisplay(dpy);
SyncHandle();
}