Array-index based devPrivates implementation.
Note: DevPrivateKey is now pointer-to-int, which means each key now needs to point to some global storage of size at least sizeof(int).
This commit is contained in:
parent
999f3362d5
commit
b6ab114212
207
dix/privates.c
207
dix/privates.c
|
@ -40,9 +40,8 @@ from The Open Group.
|
||||||
#include "inputstr.h"
|
#include "inputstr.h"
|
||||||
|
|
||||||
struct _Private {
|
struct _Private {
|
||||||
DevPrivateKey key;
|
int state;
|
||||||
pointer value;
|
pointer value;
|
||||||
struct _Private *next;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct _PrivateDesc {
|
typedef struct _PrivateDesc {
|
||||||
|
@ -50,22 +49,36 @@ typedef struct _PrivateDesc {
|
||||||
unsigned size;
|
unsigned size;
|
||||||
CallbackListPtr initfuncs;
|
CallbackListPtr initfuncs;
|
||||||
CallbackListPtr deletefuncs;
|
CallbackListPtr deletefuncs;
|
||||||
struct _PrivateDesc *next;
|
|
||||||
} PrivateDescRec;
|
} PrivateDescRec;
|
||||||
|
|
||||||
/* list of all allocated privates */
|
#define PRIV_MAX 256
|
||||||
static PrivateDescRec *items = NULL;
|
#define PRIV_STEP 16
|
||||||
|
|
||||||
static _X_INLINE PrivateDescRec *
|
/* list of all allocated privates */
|
||||||
|
static PrivateDescRec items[PRIV_MAX];
|
||||||
|
static int nextPriv;
|
||||||
|
|
||||||
|
static PrivateDescRec *
|
||||||
findItem(const DevPrivateKey key)
|
findItem(const DevPrivateKey key)
|
||||||
{
|
{
|
||||||
PrivateDescRec *item = items;
|
if (!*key) {
|
||||||
while (item) {
|
if (nextPriv >= PRIV_MAX)
|
||||||
if (item->key == key)
|
return NULL;
|
||||||
return item;
|
|
||||||
item = item->next;
|
items[nextPriv].key = key;
|
||||||
|
*key = nextPriv;
|
||||||
|
nextPriv++;
|
||||||
}
|
}
|
||||||
return NULL;
|
|
||||||
|
return items + *key;
|
||||||
|
}
|
||||||
|
|
||||||
|
static _X_INLINE int
|
||||||
|
privateExists(PrivateRec **privates, const DevPrivateKey key)
|
||||||
|
{
|
||||||
|
return *key && *privates &&
|
||||||
|
(*privates)[0].state > *key &&
|
||||||
|
(*privates)[*key].state;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -75,21 +88,10 @@ _X_EXPORT int
|
||||||
dixRequestPrivate(const DevPrivateKey key, unsigned size)
|
dixRequestPrivate(const DevPrivateKey key, unsigned size)
|
||||||
{
|
{
|
||||||
PrivateDescRec *item = findItem(key);
|
PrivateDescRec *item = findItem(key);
|
||||||
if (item) {
|
if (!item)
|
||||||
if (size > item->size)
|
return FALSE;
|
||||||
item->size = size;
|
if (size > item->size)
|
||||||
} else {
|
|
||||||
item = (PrivateDescRec *)xalloc(sizeof(PrivateDescRec));
|
|
||||||
if (!item)
|
|
||||||
return FALSE;
|
|
||||||
memset(item, 0, sizeof(PrivateDescRec));
|
|
||||||
|
|
||||||
/* add privates descriptor */
|
|
||||||
item->key = key;
|
|
||||||
item->size = size;
|
item->size = size;
|
||||||
item->next = items;
|
|
||||||
items = item;
|
|
||||||
}
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,25 +102,52 @@ _X_EXPORT pointer *
|
||||||
dixAllocatePrivate(PrivateRec **privates, const DevPrivateKey key)
|
dixAllocatePrivate(PrivateRec **privates, const DevPrivateKey key)
|
||||||
{
|
{
|
||||||
PrivateDescRec *item = findItem(key);
|
PrivateDescRec *item = findItem(key);
|
||||||
|
PrivateCallbackRec calldata;
|
||||||
PrivateRec *ptr;
|
PrivateRec *ptr;
|
||||||
unsigned size = sizeof(PrivateRec);
|
pointer value;
|
||||||
|
int oldsize, newsize;
|
||||||
if (item)
|
|
||||||
size += item->size;
|
|
||||||
|
|
||||||
ptr = (PrivateRec *)xcalloc(size, 1);
|
newsize = (*key / PRIV_STEP + 1) * PRIV_STEP;
|
||||||
if (!ptr)
|
|
||||||
|
/* resize or init privates array */
|
||||||
|
if (!item)
|
||||||
return NULL;
|
return NULL;
|
||||||
ptr->key = key;
|
|
||||||
ptr->value = (size > sizeof(PrivateRec)) ? (ptr + 1) : NULL;
|
|
||||||
ptr->next = *privates;
|
|
||||||
*privates = ptr;
|
|
||||||
|
|
||||||
/* call any init funcs and return */
|
/* initialize privates array if necessary */
|
||||||
if (item) {
|
if (!*privates) {
|
||||||
PrivateCallbackRec calldata = { key, &ptr->value };
|
ptr = xcalloc(newsize, sizeof(*ptr));
|
||||||
CallCallbacks(&item->initfuncs, &calldata);
|
if (!ptr)
|
||||||
|
return NULL;
|
||||||
|
*privates = ptr;
|
||||||
|
(*privates)[0].state = newsize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
oldsize = (*privates)[0].state;
|
||||||
|
|
||||||
|
/* resize privates array if necessary */
|
||||||
|
if (*key >= oldsize) {
|
||||||
|
ptr = xrealloc(*privates, newsize * sizeof(*ptr));
|
||||||
|
if (!ptr)
|
||||||
|
return NULL;
|
||||||
|
memset(ptr + oldsize, 0, (newsize - oldsize) * sizeof(*ptr));
|
||||||
|
*privates = ptr;
|
||||||
|
(*privates)[0].state = newsize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* initialize slot */
|
||||||
|
ptr = *privates + *key;
|
||||||
|
ptr->state = 1;
|
||||||
|
if (item->size) {
|
||||||
|
value = xcalloc(item->size, 1);
|
||||||
|
if (!value)
|
||||||
|
return NULL;
|
||||||
|
ptr->value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
calldata.key = key;
|
||||||
|
calldata.value = &ptr->value;
|
||||||
|
CallCallbacks(&item->initfuncs, &calldata);
|
||||||
|
|
||||||
return &ptr->value;
|
return &ptr->value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,14 +157,10 @@ dixAllocatePrivate(PrivateRec **privates, const DevPrivateKey key)
|
||||||
_X_EXPORT pointer
|
_X_EXPORT pointer
|
||||||
dixLookupPrivate(PrivateRec **privates, const DevPrivateKey key)
|
dixLookupPrivate(PrivateRec **privates, const DevPrivateKey key)
|
||||||
{
|
{
|
||||||
PrivateRec *rec = *privates;
|
|
||||||
pointer *ptr;
|
pointer *ptr;
|
||||||
|
|
||||||
while (rec) {
|
if (privateExists(privates, key))
|
||||||
if (rec->key == key)
|
return (*privates)[*key].value;
|
||||||
return rec->value;
|
|
||||||
rec = rec->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
ptr = dixAllocatePrivate(privates, key);
|
ptr = dixAllocatePrivate(privates, key);
|
||||||
return ptr ? *ptr : NULL;
|
return ptr ? *ptr : NULL;
|
||||||
|
@ -147,13 +172,8 @@ dixLookupPrivate(PrivateRec **privates, const DevPrivateKey key)
|
||||||
_X_EXPORT pointer *
|
_X_EXPORT pointer *
|
||||||
dixLookupPrivateAddr(PrivateRec **privates, const DevPrivateKey key)
|
dixLookupPrivateAddr(PrivateRec **privates, const DevPrivateKey key)
|
||||||
{
|
{
|
||||||
PrivateRec *rec = *privates;
|
if (privateExists(privates, key))
|
||||||
|
return &(*privates)[*key].value;
|
||||||
while (rec) {
|
|
||||||
if (rec->key == key)
|
|
||||||
return &rec->value;
|
|
||||||
rec = rec->next;
|
|
||||||
}
|
|
||||||
|
|
||||||
return dixAllocatePrivate(privates, key);
|
return dixAllocatePrivate(privates, key);
|
||||||
}
|
}
|
||||||
|
@ -164,16 +184,10 @@ dixLookupPrivateAddr(PrivateRec **privates, const DevPrivateKey key)
|
||||||
_X_EXPORT int
|
_X_EXPORT int
|
||||||
dixSetPrivate(PrivateRec **privates, const DevPrivateKey key, pointer val)
|
dixSetPrivate(PrivateRec **privates, const DevPrivateKey key, pointer val)
|
||||||
{
|
{
|
||||||
PrivateRec *rec;
|
|
||||||
|
|
||||||
top:
|
top:
|
||||||
rec = *privates;
|
if (privateExists(privates, key)) {
|
||||||
while (rec) {
|
(*privates)[*key].value = val;
|
||||||
if (rec->key == key) {
|
return TRUE;
|
||||||
rec->value = val;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
rec = rec->next;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!dixAllocatePrivate(privates, key))
|
if (!dixAllocatePrivate(privates, key))
|
||||||
|
@ -187,27 +201,23 @@ dixSetPrivate(PrivateRec **privates, const DevPrivateKey key, pointer val)
|
||||||
_X_EXPORT void
|
_X_EXPORT void
|
||||||
dixFreePrivates(PrivateRec *privates)
|
dixFreePrivates(PrivateRec *privates)
|
||||||
{
|
{
|
||||||
PrivateRec *ptr, *next;
|
int i;
|
||||||
PrivateDescRec *item;
|
|
||||||
PrivateCallbackRec calldata;
|
PrivateCallbackRec calldata;
|
||||||
|
|
||||||
/* first pass calls the delete callbacks */
|
if (privates)
|
||||||
for (ptr = privates; ptr; ptr = ptr->next) {
|
for (i = 1; i < privates->state; i++)
|
||||||
item = findItem(ptr->key);
|
if (privates[i].state) {
|
||||||
if (item) {
|
/* call the delete callbacks */
|
||||||
calldata.key = ptr->key;
|
calldata.key = items[i].key;
|
||||||
calldata.value = &ptr->value;
|
calldata.value = &privates[i].value;
|
||||||
CallCallbacks(&item->deletefuncs, &calldata);
|
CallCallbacks(&items[i].deletefuncs, &calldata);
|
||||||
}
|
|
||||||
}
|
/* free pre-allocated memory */
|
||||||
|
if (items[i].size)
|
||||||
/* second pass frees the memory */
|
xfree(privates[i].value);
|
||||||
ptr = privates;
|
}
|
||||||
while (ptr) {
|
|
||||||
next = ptr->next;
|
xfree(privates);
|
||||||
xfree(ptr);
|
|
||||||
ptr = next;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -218,11 +228,9 @@ dixRegisterPrivateInitFunc(const DevPrivateKey key,
|
||||||
CallbackProcPtr callback, pointer data)
|
CallbackProcPtr callback, pointer data)
|
||||||
{
|
{
|
||||||
PrivateDescRec *item = findItem(key);
|
PrivateDescRec *item = findItem(key);
|
||||||
if (!item) {
|
if (!item)
|
||||||
if (!dixRequestPrivate(key, 0))
|
return FALSE;
|
||||||
return FALSE;
|
|
||||||
item = findItem(key);
|
|
||||||
}
|
|
||||||
return AddCallback(&item->initfuncs, callback, data);
|
return AddCallback(&item->initfuncs, callback, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -231,11 +239,9 @@ dixRegisterPrivateDeleteFunc(const DevPrivateKey key,
|
||||||
CallbackProcPtr callback, pointer data)
|
CallbackProcPtr callback, pointer data)
|
||||||
{
|
{
|
||||||
PrivateDescRec *item = findItem(key);
|
PrivateDescRec *item = findItem(key);
|
||||||
if (!item) {
|
if (!item)
|
||||||
if (!dixRequestPrivate(key, 0))
|
return FALSE;
|
||||||
return FALSE;
|
|
||||||
item = findItem(key);
|
|
||||||
}
|
|
||||||
return AddCallback(&item->deletefuncs, callback, data);
|
return AddCallback(&item->deletefuncs, callback, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -292,16 +298,17 @@ dixLookupPrivateOffset(RESTYPE type)
|
||||||
int
|
int
|
||||||
dixResetPrivates(void)
|
dixResetPrivates(void)
|
||||||
{
|
{
|
||||||
PrivateDescRec *next;
|
int i;
|
||||||
|
|
||||||
/* reset internal structures */
|
/* reset private descriptors */
|
||||||
while (items) {
|
for (i = 1; i < nextPriv; i++) {
|
||||||
next = items->next;
|
*items[i].key = 0;
|
||||||
DeleteCallbackList(&items->initfuncs);
|
DeleteCallbackList(&items[i].initfuncs);
|
||||||
DeleteCallbackList(&items->deletefuncs);
|
DeleteCallbackList(&items[i].deletefuncs);
|
||||||
xfree(items);
|
|
||||||
items = next;
|
|
||||||
}
|
}
|
||||||
|
nextPriv = 1;
|
||||||
|
|
||||||
|
/* reset offsets */
|
||||||
if (offsets)
|
if (offsets)
|
||||||
xfree(offsets);
|
xfree(offsets);
|
||||||
offsetsSize = sizeof(offsetDefaults);
|
offsetsSize = sizeof(offsetDefaults);
|
||||||
|
|
|
@ -19,7 +19,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
* STUFF FOR PRIVATES
|
* STUFF FOR PRIVATES
|
||||||
*****************************************************************/
|
*****************************************************************/
|
||||||
|
|
||||||
typedef void *DevPrivateKey;
|
typedef int *DevPrivateKey;
|
||||||
struct _Private;
|
struct _Private;
|
||||||
typedef struct _Private PrivateRec;
|
typedef struct _Private PrivateRec;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue