зеркало из https://github.com/mozilla/gecko-dev.git
Change the attribute allocation scheme to a fixed array in the object.
This commit is contained in:
Родитель
0430e9e67e
Коммит
984310dddf
|
@ -474,17 +474,6 @@ pk11_defaultAttribute(PK11Object *object,CK_ATTRIBUTE_TYPE type,void *value,
|
|||
return CKR_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* overwrite a potential existing attribute with a new value
|
||||
*/
|
||||
CK_RV
|
||||
pk11_forceAttribute(PK11Object *object,CK_ATTRIBUTE_TYPE type,void *value,
|
||||
unsigned int len)
|
||||
{
|
||||
pk11_DeleteAttributeType(object,type);
|
||||
return pk11_AddAttributeType(object,type,value,len);
|
||||
}
|
||||
|
||||
/*
|
||||
* check the consistancy and initialize a Data Object
|
||||
*/
|
||||
|
|
|
@ -44,6 +44,11 @@
|
|||
|
||||
#define PKCS11_USE_THREADS
|
||||
|
||||
#define NO_ARENA
|
||||
#define MAX_OBJS_ATTRS 45
|
||||
#define ATTR_SPACE 50 /* hold up to a SSL premaster secret */
|
||||
|
||||
|
||||
#ifdef PKCS11_USE_THREADS
|
||||
#define PK11_USE_THREADS(x) x
|
||||
#else
|
||||
|
@ -119,6 +124,9 @@ struct PK11AttributeStr {
|
|||
/*must be called handle to make pk11queue_find work */
|
||||
CK_ATTRIBUTE_TYPE handle;
|
||||
CK_ATTRIBUTE attrib;
|
||||
#ifdef NO_ARENA
|
||||
unsigned char space[ATTR_SPACE];
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
|
@ -139,7 +147,11 @@ struct PK11ObjectStr {
|
|||
PK11Object *prev;
|
||||
PK11ObjectList sessionList;
|
||||
CK_OBJECT_HANDLE handle;
|
||||
#ifdef NO_ARENA
|
||||
int nextAttr;
|
||||
#else
|
||||
PLArenaPool *arena;
|
||||
#endif
|
||||
int refCount;
|
||||
PRLock *refLock;
|
||||
PRLock *attributeLock;
|
||||
|
@ -152,6 +164,9 @@ struct PK11ObjectStr {
|
|||
PRBool inDB;
|
||||
PRBool wasDerived;
|
||||
PK11Attribute *head[ATTRIBUTE_HASH_SIZE];
|
||||
#ifdef NO_ARENA
|
||||
PK11Attribute attrList[MAX_OBJS_ATTRS];
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -56,29 +56,34 @@ static PK11Slot pk11_slot[3];
|
|||
* to hold value.
|
||||
*/
|
||||
static PK11Attribute *
|
||||
pk11_NewAttribute(PLArenaPool *arena,
|
||||
pk11_NewAttribute(PK11Object *object,
|
||||
CK_ATTRIBUTE_TYPE type, CK_VOID_PTR value, CK_ULONG len)
|
||||
{
|
||||
PK11Attribute *attribute;
|
||||
|
||||
#ifdef REF_COUNT_ATTRIBUTE
|
||||
attribute = (PK11Attribute*)PORT_Alloc(sizeof(PK11Attribute));
|
||||
#else
|
||||
attribute = (PK11Attribute*)PORT_ArenaAlloc(arena,sizeof(PK11Attribute));
|
||||
#endif
|
||||
if (attribute == NULL) return NULL;
|
||||
#ifdef NO_ARENA
|
||||
int index;
|
||||
/*
|
||||
* NO_ARENA attempts to keep down contention on Malloc and Arena locks
|
||||
* by limiting the number of these calls on high traversed paths. this
|
||||
* is done for attributes by 'allocating' them from a pool already allocated
|
||||
* by the parent object.
|
||||
*/
|
||||
PK11_USE_THREADS(PR_Lock(object->attributeLock);)
|
||||
index = object->nextAttr++;
|
||||
PK11_USE_THREADS(PR_Unlock(object->attributeLock);)
|
||||
PORT_Assert(index < MAX_OBJS_ATTRS);
|
||||
if (index >= MAX_OBJS_ATTRS) return NULL;
|
||||
|
||||
attribute = &object->attrList[index];
|
||||
attribute->attrib.type = type;
|
||||
if (value) {
|
||||
#ifdef REF_COUNT_ATTRIBUTE
|
||||
attribute->attrib.pValue = PORT_Alloc(len);
|
||||
#else
|
||||
attribute->attrib.pValue = PORT_ArenaAlloc(arena,len);
|
||||
#endif
|
||||
if (len <= ATTR_SPACE) {
|
||||
attribute->attrib.pValue = attribute->space;
|
||||
} else {
|
||||
attribute->attrib.pValue = PORT_Alloc(len);
|
||||
}
|
||||
if (attribute->attrib.pValue == NULL) {
|
||||
#ifdef REF_COUNT_ATTRIBUTE
|
||||
PORT_Free(attribute);
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
PORT_Memcpy(attribute->attrib.pValue,value,len);
|
||||
|
@ -87,6 +92,34 @@ pk11_NewAttribute(PLArenaPool *arena,
|
|||
attribute->attrib.pValue = NULL;
|
||||
attribute->attrib.ulValueLen = 0;
|
||||
}
|
||||
#else
|
||||
#ifdef REF_COUNT_ATTRIBUTE
|
||||
attribute = (PK11Attribute*)PORT_Alloc(sizeof(PK11Attribute));
|
||||
#else
|
||||
attribute = (PK11Attribute*)PORT_ArenaAlloc(object->arena,sizeof(PK11Attribute));
|
||||
#endif /* REF_COUNT_ATTRIBUTE */
|
||||
if (attribute == NULL) return NULL;
|
||||
|
||||
if (value) {
|
||||
#ifdef REF_COUNT_ATTRIBUTE
|
||||
attribute->attrib.pValue = PORT_Alloc(len);
|
||||
#else
|
||||
attribute->attrib.pValue = PORT_ArenaAlloc(object->arena,len);
|
||||
#endif /* REF_COUNT_ATTRIBUTE */
|
||||
if (attribute->attrib.pValue == NULL) {
|
||||
#ifdef REF_COUNT_ATTRIBUTE
|
||||
PORT_Free(attribute);
|
||||
#endif /* REF_COUNT_ATTRIBUTE */
|
||||
return NULL;
|
||||
}
|
||||
PORT_Memcpy(attribute->attrib.pValue,value,len);
|
||||
attribute->attrib.ulValueLen = len;
|
||||
} else {
|
||||
attribute->attrib.pValue = NULL;
|
||||
attribute->attrib.ulValueLen = 0;
|
||||
}
|
||||
#endif /* NO_ARENA */
|
||||
attribute->attrib.type = type;
|
||||
attribute->handle = type;
|
||||
attribute->next = attribute->prev = NULL;
|
||||
#ifdef REF_COUNT_ATTRIBUTE
|
||||
|
@ -101,7 +134,7 @@ pk11_NewAttribute(PLArenaPool *arena,
|
|||
#else
|
||||
attribute->refLock = NULL;
|
||||
#endif
|
||||
#endif
|
||||
#endif /* REF_COUNT_ATTRIBUTE */
|
||||
return attribute;
|
||||
}
|
||||
|
||||
|
@ -288,13 +321,78 @@ pk11_nullAttribute(PK11Object *object,CK_ATTRIBUTE_TYPE type)
|
|||
PORT_Memset(attribute->attrib.pValue,0,attribute->attrib.ulValueLen);
|
||||
#ifdef REF_COUNT_ATTRIBUTE
|
||||
PORT_Free(attribute->attrib.pValue);
|
||||
#endif
|
||||
#endif /* REF_COUNT_ATTRIBUTE */
|
||||
#ifdef NO_ARENA
|
||||
if (attribute->attrib.pValue != attribute->space) {
|
||||
PORT_Free(attribute->attrib.pValue);
|
||||
}
|
||||
#endif /* NO_ARENA */
|
||||
attribute->attrib.pValue = NULL;
|
||||
attribute->attrib.ulValueLen = 0;
|
||||
}
|
||||
pk11_FreeAttribute(attribute);
|
||||
}
|
||||
|
||||
/*
|
||||
* force an attribute to a spaecif value.
|
||||
*/
|
||||
CK_RV
|
||||
pk11_forceAttribute(PK11Object *object,CK_ATTRIBUTE_TYPE type, void *value,
|
||||
unsigned int len)
|
||||
{
|
||||
PK11Attribute *attribute;
|
||||
void *att_val = NULL;
|
||||
|
||||
attribute=pk11_FindAttribute(object,type);
|
||||
if (attribute == NULL) return pk11_AddAttributeType(object,type,value,len);
|
||||
|
||||
|
||||
if (value) {
|
||||
#ifdef NO_ARENA
|
||||
if (len <= ATTR_SPACE) {
|
||||
att_val = attribute->space;
|
||||
} else {
|
||||
att_val = PORT_Alloc(len);
|
||||
}
|
||||
#else
|
||||
#ifdef REF_COUNT_ATTRIBUTE
|
||||
att_val = PORT_Alloc(len);
|
||||
#else
|
||||
att_val = PORT_ArenaAlloc(object->arena,len);
|
||||
#endif /* REF_COUNT_ATTRIBUTE */
|
||||
#endif /* NO_ARENA */
|
||||
if (att_val == NULL) {
|
||||
return CKR_HOST_MEMORY;
|
||||
}
|
||||
if (attribute->attrib.pValue == att_val) {
|
||||
PORT_Memset(attribute->attrib.pValue,0,
|
||||
attribute->attrib.ulValueLen);
|
||||
}
|
||||
PORT_Memcpy(att_val,value,len);
|
||||
}
|
||||
if (attribute->attrib.pValue != NULL) {
|
||||
if (attribute->attrib.pValue != att_val) {
|
||||
PORT_Memset(attribute->attrib.pValue,0,
|
||||
attribute->attrib.ulValueLen);
|
||||
}
|
||||
#ifdef REF_COUNT_ATTRIBUTE
|
||||
PORT_Free(attribute->attrib.pValue);
|
||||
#endif /* REF_COUNT_ATTRIBUTE */
|
||||
#ifdef NO_ARENA
|
||||
if (attribute->attrib.pValue != attribute->space) {
|
||||
PORT_Free(attribute->attrib.pValue);
|
||||
}
|
||||
#endif /* NO_ARENA */
|
||||
attribute->attrib.pValue = NULL;
|
||||
attribute->attrib.ulValueLen = 0;
|
||||
}
|
||||
if (att_val) {
|
||||
attribute->attrib.pValue = att_val;
|
||||
attribute->attrib.ulValueLen = len;
|
||||
}
|
||||
return CKR_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* return a null terminated string from attribute 'type'. This string
|
||||
* is allocated and needs to be freed with PORT_Free() When complete.
|
||||
|
@ -482,7 +580,7 @@ pk11_AddAttributeType(PK11Object *object,CK_ATTRIBUTE_TYPE type,void *valPtr,
|
|||
CK_ULONG length)
|
||||
{
|
||||
PK11Attribute *attribute;
|
||||
attribute = pk11_NewAttribute(object->arena,type,valPtr,length);
|
||||
attribute = pk11_NewAttribute(object,type,valPtr,length);
|
||||
if (attribute == NULL) { return CKR_HOST_MEMORY; }
|
||||
pk11_AddAttribute(object,attribute);
|
||||
return CKR_OK;
|
||||
|
@ -492,6 +590,23 @@ pk11_AddAttributeType(PK11Object *object,CK_ATTRIBUTE_TYPE type,void *valPtr,
|
|||
* ******************** Object Utilities *******************************
|
||||
*/
|
||||
|
||||
/* allocation hooks that allow us to recycle old object structures */
|
||||
static PK11Object *
|
||||
pk11_GetObjectFromList(PRBool *hasLocks) {
|
||||
PK11Object *object = (PK11Object*)PORT_ZAlloc(sizeof(PK11Object));
|
||||
*hasLocks = PR_FALSE;
|
||||
return object;
|
||||
}
|
||||
|
||||
static void
|
||||
pk11_PutObjectToList(PK11Object *object) {
|
||||
PK11_USE_THREADS(PR_DestroyLock(object->attributeLock);)
|
||||
PK11_USE_THREADS(PR_DestroyLock(object->refLock);)
|
||||
object->attributeLock = object->refLock = NULL;
|
||||
PORT_Free(object);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Create a new object
|
||||
*/
|
||||
|
@ -500,8 +615,17 @@ pk11_NewObject(PK11Slot *slot)
|
|||
{
|
||||
PK11Object *object;
|
||||
PLArenaPool *arena;
|
||||
PRBool hasLocks = PR_FALSE;
|
||||
int i;
|
||||
|
||||
|
||||
#ifdef NO_ARENA
|
||||
object = pk11_GetObjectFromList(&hasLocks);
|
||||
if (object == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
object->nextAttr = 0;
|
||||
#else
|
||||
arena = PORT_NewArena(2048);
|
||||
if (arena == NULL) return NULL;
|
||||
|
||||
|
@ -510,9 +634,14 @@ pk11_NewObject(PK11Slot *slot)
|
|||
PORT_FreeArena(arena,PR_FALSE);
|
||||
return NULL;
|
||||
}
|
||||
object->arena = arena;
|
||||
|
||||
for (i=0; i < MAX_OBJS_ATTRS; i++) {
|
||||
object->attrList[i].attrib.pValue = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
object->handle = 0;
|
||||
object->arena = arena;
|
||||
object->next = object->prev = NULL;
|
||||
object->sessionList.next = NULL;
|
||||
object->sessionList.prev = NULL;
|
||||
|
@ -525,15 +654,23 @@ pk11_NewObject(PK11Slot *slot)
|
|||
object->objclass = 0xffff;
|
||||
object->wasDerived = PR_FALSE;
|
||||
#ifdef PKCS11_USE_THREADS
|
||||
object->refLock = PR_NewLock();
|
||||
if (!hasLocks) object->refLock = PR_NewLock();
|
||||
if (object->refLock == NULL) {
|
||||
#ifdef NO_ARENA
|
||||
PORT_Free(object);
|
||||
#else
|
||||
PORT_FreeArena(arena,PR_FALSE);
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
object->attributeLock = PR_NewLock();
|
||||
if (!hasLocks) object->attributeLock = PR_NewLock();
|
||||
if (object->attributeLock == NULL) {
|
||||
PK11_USE_THREADS(PR_DestroyLock(object->refLock);)
|
||||
#ifdef NO_ARENA
|
||||
PORT_Free(object);
|
||||
#else
|
||||
PORT_FreeArena(arena,PR_FALSE);
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
#else
|
||||
|
@ -555,7 +692,7 @@ pk11_NewObject(PK11Slot *slot)
|
|||
static CK_RV
|
||||
pk11_DestroyObject(PK11Object *object)
|
||||
{
|
||||
#ifdef REF_COUNT_ATTRIBUTE
|
||||
#if defined(REF_COUNT_ATTRIBUTE) || defined(NO_ARENA)
|
||||
int i;
|
||||
#endif
|
||||
SECItem pubKey;
|
||||
|
@ -587,6 +724,22 @@ pk11_DestroyObject(PK11Object *object)
|
|||
}
|
||||
if (object->label) PORT_Free(object->label);
|
||||
|
||||
object->inDB = PR_FALSE;
|
||||
object->label = NULL;
|
||||
|
||||
#ifdef NO_ARENA
|
||||
for (i=0; i < MAX_OBJS_ATTRS; i++) {
|
||||
unsigned char *value = object->attrList[i].attrib.pValue;
|
||||
if (value) {
|
||||
PORT_Memset(value,0,object->attrList[i].attrib.ulValueLen);
|
||||
if (value != object->attrList[i].space) {
|
||||
PORT_Free(value);
|
||||
}
|
||||
object->attrList[i].attrib.pValue = NULL;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef REF_COUNT_ATTRIBUTE
|
||||
/* clean out the attributes */
|
||||
/* since no one is referencing us, it's safe to walk the chain
|
||||
|
@ -602,13 +755,17 @@ pk11_DestroyObject(PK11Object *object)
|
|||
object->head[i] = NULL;
|
||||
}
|
||||
#endif
|
||||
PK11_USE_THREADS(PR_DestroyLock(object->attributeLock);)
|
||||
PK11_USE_THREADS(PR_DestroyLock(object->refLock);)
|
||||
if (object->objectInfo) {
|
||||
(*object->infoFree)(object->objectInfo);
|
||||
}
|
||||
#ifdef NO_ARENA
|
||||
pk11_PutObjectToList(object);
|
||||
#else
|
||||
PK11_USE_THREADS(PR_DestroyLock(object->attributeLock);)
|
||||
PK11_USE_THREADS(PR_DestroyLock(object->refLock);)
|
||||
arena = object->arena;
|
||||
PORT_FreeArena(arena,PR_FALSE);
|
||||
#endif
|
||||
return crv;
|
||||
}
|
||||
|
||||
|
@ -744,8 +901,7 @@ pk11_CopyObject(PK11Object *destObject,PK11Object *srcObject)
|
|||
/* we need to copy the attribute since each attribute
|
||||
* only has one set of link list pointers */
|
||||
PK11Attribute *newAttribute = pk11_NewAttribute(
|
||||
destObject->arena,
|
||||
pk11_attr_expand(&attribute->attrib));
|
||||
destObject,pk11_attr_expand(&attribute->attrib));
|
||||
if (newAttribute == NULL) {
|
||||
PK11_USE_THREADS(PR_Unlock(srcObject->attributeLock);)
|
||||
return CKR_HOST_MEMORY;
|
||||
|
|
Загрузка…
Ссылка в новой задаче