summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2010-04-30 19:36:33 -0700
committerKeith Packard <keithp@keithp.com>2010-06-05 19:31:37 -0700
commit34db537907c6cb2635dbefdce7dcfcae90f7c902 (patch)
treeb435c01d1f56e043ecaa43cca0ac56d3dbfd7e61
parent495fc3eb2d6c98bde82ae1278f89fcf131fd9bf8 (diff)
Add dixCreatePrivateKey API
Keys need to persist through server reset so that the private system can be cleaned up in dixResetPrivates. In particular, this means that keys cannot live in objects freed at reset time. This API provides suitable object lifetime by having the privates code free the key in the reset path. Signed-off-by: Keith Packard <keithp@keithp.com> Reviewed-by: Jamey Sharp <jamey@minilop.net>
-rw-r--r--dix/privates.c32
-rw-r--r--include/privates.h12
2 files changed, 42 insertions, 2 deletions
diff --git a/dix/privates.c b/dix/privates.c
index 736e950f1..ec818d411 100644
--- a/dix/privates.c
+++ b/dix/privates.c
@@ -229,6 +229,7 @@ dixRegisterPrivateKey(DevPrivateKey key, DevPrivateType type, unsigned size)
key->size = size;
key->initialized = TRUE;
key->type = type;
+ key->allocated = FALSE;
key->next = keys[type].key;
keys[type].key = key;
@@ -236,6 +237,30 @@ dixRegisterPrivateKey(DevPrivateKey key, DevPrivateType type, unsigned size)
}
/*
+ * Allocate a new private key.
+ *
+ * This manages the storage of the key object itself, freeing it when the
+ * privates system is restarted at server reset time. All other keys
+ * are expected to be statically allocated as the privates must be
+ * reset after all objects have been freed
+ */
+DevPrivateKey
+dixCreatePrivateKey(DevPrivateType type, unsigned size)
+{
+ DevPrivateKey key;
+
+ key = calloc(sizeof (DevPrivateKeyRec), 1);
+ if (!key)
+ return NULL;
+ if (!dixRegisterPrivateKey(key, type, size)) {
+ free(key);
+ return NULL;
+ }
+ key->allocated = TRUE;
+ return key;
+}
+
+/*
* Initialize privates by zeroing them
*/
void
@@ -444,13 +469,16 @@ dixResetPrivates(void)
DevPrivateType t;
for (t = PRIVATE_XSELINUX; t < PRIVATE_LAST; t++) {
- DevPrivateKey key;
+ DevPrivateKey key, next;
- for (key = keys[t].key; key; key = key->next) {
+ for (key = keys[t].key; key; key = next) {
+ next = key->next;
key->offset = 0;
key->initialized = FALSE;
key->size = 0;
key->type = 0;
+ if (key->allocated)
+ free(key);
}
if (keys[t].created) {
ErrorF("%d %ss still allocated at reset\n",
diff --git a/include/privates.h b/include/privates.h
index e2bdafda5..4fed7d058 100644
--- a/include/privates.h
+++ b/include/privates.h
@@ -60,6 +60,7 @@ typedef struct _DevPrivateKeyRec {
int offset;
int size;
Bool initialized;
+ Bool allocated;
DevPrivateType type;
struct _DevPrivateKeyRec *next;
} DevPrivateKeyRec, *DevPrivateKey;
@@ -99,6 +100,17 @@ dixPrivateKeyRegistered(DevPrivateKey key)
}
/*
+ * Allocate a new private key.
+ *
+ * This manages the storage of the key object itself, freeing it when the
+ * privates system is restarted at server reset time. All other keys
+ * are expected to be statically allocated as the privates must be
+ * reset after all objects have been freed
+ */
+extern _X_EXPORT DevPrivateKey
+dixCreatePrivateKey(DevPrivateType type, unsigned size);
+
+/*
* Get the address of the private storage.
*
* For keys with pre-defined storage, this gets the base of that storage