summaryrefslogtreecommitdiff
path: root/randr
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2018-06-26 09:20:00 -0700
committerAdam Jackson <ajax@redhat.com>2018-08-02 10:15:26 -0400
commit1ef7aed3e2bb2af32330f19b1e7560000512ddfe (patch)
tree2edefe349eb4acd3dded69771ae792e6528496bd /randr
parentd625e16918ef9104863709eb108346464767c444 (diff)
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>
Diffstat (limited to 'randr')
-rw-r--r--randr/randr.c4
-rw-r--r--randr/randrstr.h3
-rw-r--r--randr/rrcrtc.c11
-rw-r--r--randr/rrlease.c2
-rw-r--r--randr/rroutput.c11
5 files changed, 30 insertions, 1 deletions
diff --git a/randr/randr.c b/randr/randr.c
index feb54bcc8..5db8b5ced 100644
--- a/randr/randr.c
+++ b/randr/randr.c
@@ -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--)
diff --git a/randr/randrstr.h b/randr/randrstr.h
index f94174b54..2cede92e3 100644
--- a/randr/randrstr.h
+++ b/randr/randrstr.h
@@ -829,6 +829,9 @@ RRCrtcIsLeased(RRCrtcPtr crtc);
extern _X_EXPORT Bool
RROutputIsLeased(RROutputPtr output);
+void
+RRTerminateLease(RRLeasePtr lease);
+
Bool
RRLeaseInit(void);
diff --git a/randr/rrcrtc.c b/randr/rrcrtc.c
index 74dc5a265..5d9026266 100644
--- a/randr/rrcrtc.c
+++ b/randr/rrcrtc.c
@@ -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) {
diff --git a/randr/rrlease.c b/randr/rrlease.c
index b4a8827cc..e25d9ca99 100644
--- a/randr/rrlease.c
+++ b/randr/rrlease.c
@@ -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;
diff --git a/randr/rroutput.c b/randr/rroutput.c
index 33300e1cc..e52ad7671 100644
--- a/randr/rroutput.c
+++ b/randr/rroutput.c
@@ -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;