During reset/shutdown, clean up leases in DIX instead of each driver

Instead of having every video driver loop over any pending leases to
free them during CloseScreen, do this up in the DIX layer by
terminating leases when a leased CRTC or Output is destroyed and
(just to make sure), also terminating leases in RRCloseScreen. The
latter should "never" get invoked as any lease should be associated
with a resource which was destroyed.

This is required as by the time the driver's CloseScreen function is
invoked, we've already freed all of the DIX randr structures and no
longer have any way to reference the leases

Signed-off-by: Keith Packard <keithp@keithp.com>
Fixes: https://bugs.freedesktop.org/show_bug.cgi?id=106960
Cc: Thomas Hellstrom <thellstrom@vmware.com>
This commit is contained in:
Keith Packard 2018-06-26 09:20:00 -07:00 • committed by Adam Jackson
commit 1ef7aed3e2
8 changed files with 30 additions and 22 deletions

View file

@ -89,8 +89,12 @@ RRCloseScreen(ScreenPtr pScreen)
{
rrScrPriv(pScreen);
int j;
RRLeasePtr lease, next;
unwrap(pScrPriv, pScreen, CloseScreen);
xorg_list_for_each_entry_safe(lease, next, &pScrPriv->leases, list)
RRTerminateLease(lease);
for (j = pScrPriv->numCrtcs - 1; j >= 0; j--)
RRCrtcDestroy(pScrPriv->crtcs[j]);
for (j = pScrPriv->numOutputs - 1; j >= 0; j--)

View file

@ -829,6 +829,9 @@ RRCrtcIsLeased(RRCrtcPtr crtc);
extern _X_EXPORT Bool
RROutputIsLeased(RROutputPtr output);
void
RRTerminateLease(RRLeasePtr lease);
Bool
RRLeaseInit(void);

View file

@ -872,6 +872,17 @@ RRCrtcDestroyResource(void *value, XID pid)
if (pScreen) {
rrScrPriv(pScreen);
int i;
RRLeasePtr lease, next;
xorg_list_for_each_entry_safe(lease, next, &pScrPriv->leases, list) {
int c;
for (c = 0; c < lease->numCrtcs; c++) {
if (lease->crtcs[c] == crtc) {
RRTerminateLease(lease);
break;
}
}
}
for (i = 0; i < pScrPriv->numCrtcs; i++) {
if (pScrPriv->crtcs[i] == crtc) {

View file

@ -169,7 +169,7 @@ RRLeaseFree(RRLeasePtr lease)
* finished, which may be some time after this function returns
* if the driver operation is asynchronous
*/
static void
void
RRTerminateLease(RRLeasePtr lease)
{
ScreenPtr screen = lease->screen;

View file

@ -379,6 +379,17 @@ RROutputDestroyResource(void *value, XID pid)
if (pScreen) {
rrScrPriv(pScreen);
int i;
RRLeasePtr lease, next;
xorg_list_for_each_entry_safe(lease, next, &pScrPriv->leases, list) {
int o;
for (o = 0; o < lease->numOutputs; o++) {
if (lease->outputs[o] == output) {
RRTerminateLease(lease);
break;
}
}
}
if (pScrPriv->primaryOutput == output)
pScrPriv->primaryOutput = NULL;