dix: Track DevPrivateKey initialization by generation

Submitted by Michal Srb on Nov. 23, 2018, 8:38 a.m.

Details

Message ID 20181123083859.15709-3-msrb@suse.com
State New
Headers show
Series "dix: Ignore initialized flag for screen-specific privates" ( rev: 1 ) in X.org

Not browsing as part of any series.

Commit Message

Michal Srb Nov. 23, 2018, 8:38 a.m.
The dixRegisterPrivateKey and dixRegisterScreenSpecificPrivateKey functions
must ignore key if it is being registered for second time. At the same time,
they must accept the key again after internal restart. To achive that, the
"initialized" flag existed and was cleared in dixResetPrivates and
dixFreeScreenSpecificPrivates respectively.

The dixFreeScreenSpecificPrivates was called before CloseScreen which meant
that accessing privates in it would trigger assertion failure. It could not
be called after CloseScreen, because some of the keys may be deallocated in
CloseScreen.

This patch turns the "initialized" flag into "initializedInGeneration"
counter. The key was initialized if it equals current serverGeneration. This
way no explicit clearing is needed.

The dixFreeScreenSpecificPrivates is left empty as it was before 82eb490.

Signed-off-by: Michal Srb <msrb@suse.com>
Fixes: 82eb490 (privates: Clear screen-specific keys during CloseScreen)
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=108762
---
 dix/privates.c     | 19 +++++--------------
 include/privates.h |  6 +++---
 2 files changed, 8 insertions(+), 17 deletions(-)

Patch hide | download patch | download mbox

diff --git a/dix/privates.c b/dix/privates.c
index 9ca80f0b6..ea4ec2567 100644
--- a/dix/privates.c
+++ b/dix/privates.c
@@ -337,7 +337,7 @@  dixRegisterPrivateKey(DevPrivateKey key, DevPrivateType type, unsigned size)
     int offset;
     unsigned bytes;
 
-    if (key->initialized) {
+    if (key->initializedInGeneration == (unsigned int) serverGeneration) {
         assert(size == key->size);
         return TRUE;
     }
@@ -392,7 +392,7 @@  dixRegisterPrivateKey(DevPrivateKey key, DevPrivateType type, unsigned size)
     /* Setup this key */
     key->offset = offset;
     key->size = size;
-    key->initialized = TRUE;
+    key->initializedInGeneration = (unsigned int) serverGeneration;
     key->type = type;
     key->allocated = FALSE;
     key->next = global_keys[type].key;
@@ -605,7 +605,7 @@  dixRegisterScreenSpecificPrivateKey(ScreenPtr pScreen, DevPrivateKey key,
         FatalError("Attempt to allocate screen-specific private storage for type %s\n",
                    key_names[type]);
 
-    if (key->initialized) {
+    if (key->initializedInGeneration == (unsigned int) serverGeneration) {
         assert(size == key->size);
         return TRUE;
     }
@@ -626,7 +626,7 @@  dixRegisterScreenSpecificPrivateKey(ScreenPtr pScreen, DevPrivateKey key,
     /* Setup this key */
     key->offset = offset;
     key->size = size;
-    key->initialized = TRUE;
+    key->initializedInGeneration = (unsigned int) serverGeneration;
     key->type = type;
     key->allocated = FALSE;
     key->next = pScreen->screenSpecificPrivates[type].key;
@@ -639,15 +639,6 @@  dixRegisterScreenSpecificPrivateKey(ScreenPtr pScreen, DevPrivateKey key,
 void
 dixFreeScreenSpecificPrivates(ScreenPtr pScreen)
 {
-    DevPrivateType t;
-
-    for (t = PRIVATE_XSELINUX; t < PRIVATE_LAST; t++) {
-        DevPrivateKey key;
-
-        for (key = pScreen->screenSpecificPrivates[t].key; key; key = key->next) {
-            key->initialized = FALSE;
-        }
-    }
 }
 
 /* Initialize screen-specific privates in AddScreen */
@@ -763,7 +754,7 @@  dixResetPrivates(void)
         for (key = global_keys[t].key; key; key = next) {
             next = key->next;
             key->offset = 0;
-            key->initialized = FALSE;
+            key->initializedInGeneration = 0;
             key->size = 0;
             key->type = 0;
             if (key->allocated)
diff --git a/include/privates.h b/include/privates.h
index e89c3e440..a1833b0ab 100644
--- a/include/privates.h
+++ b/include/privates.h
@@ -58,7 +58,7 @@  typedef enum {
 typedef struct _DevPrivateKeyRec {
     int offset;
     int size;
-    Bool initialized;
+    unsigned int initializedInGeneration;
     Bool allocated;
     DevPrivateType type;
     struct _DevPrivateKeyRec *next;
@@ -106,7 +106,7 @@  extern _X_EXPORT Bool
 static inline Bool
 dixPrivateKeyRegistered(DevPrivateKey key)
 {
-    return key->initialized;
+    return key->initializedInGeneration == (unsigned int) serverGeneration;
 }
 
 /*
@@ -118,7 +118,7 @@  dixPrivateKeyRegistered(DevPrivateKey key)
 static inline void *
 dixGetPrivateAddr(PrivatePtr *privates, const DevPrivateKey key)
 {
-    assert(key->initialized);
+    assert(dixPrivateKeyRegistered(key));
     return (char *) (*privates) + key->offset;
 }