char body[1];
} PROPERTY_DEFN_ELEM;
-DEFINE_LHASH_OF(PROPERTY_DEFN_ELEM);
+DEFINE_LHASH_OF_EX(PROPERTY_DEFN_ELEM);
static unsigned long property_defn_hash(const PROPERTY_DEFN_ELEM *a)
{
property_defns = ossl_lib_ctx_get_data(ctx,
OSSL_LIB_CTX_PROPERTY_DEFN_INDEX);
- if (property_defns == NULL || !ossl_lib_ctx_read_lock(ctx))
+ if (!ossl_assert(property_defns != NULL) || !ossl_lib_ctx_read_lock(ctx))
return NULL;
elem.prop = prop;
r = lh_PROPERTY_DEFN_ELEM_retrieve(property_defns, &elem);
ossl_lib_ctx_unlock(ctx);
- return r != NULL ? r->defn : NULL;
+ if (r == NULL || !ossl_assert(r->defn != NULL))
+ return NULL;
+ return r->defn;
}
+/*
+ * Cache the property list for a given property string *pl.
+ * If an entry already exists in the cache *pl is freed and
+ * overwritten with the existing entry from the cache.
+ */
int ossl_prop_defn_set(OSSL_LIB_CTX *ctx, const char *prop,
- OSSL_PROPERTY_LIST *pl)
+ OSSL_PROPERTY_LIST **pl)
{
PROPERTY_DEFN_ELEM elem, *old, *p = NULL;
size_t len;
if (!ossl_lib_ctx_write_lock(ctx))
return 0;
+ elem.prop = prop;
if (pl == NULL) {
- elem.prop = prop;
lh_PROPERTY_DEFN_ELEM_delete(property_defns, &elem);
goto end;
}
+ /* check if property definition is in the cache already */
+ if ((p = lh_PROPERTY_DEFN_ELEM_retrieve(property_defns, &elem)) != NULL) {
+ ossl_property_free(*pl);
+ *pl = p->defn;
+ goto end;
+ }
len = strlen(prop);
p = OPENSSL_malloc(sizeof(*p) + len);
if (p != NULL) {
p->prop = p->body;
- p->defn = pl;
+ p->defn = *pl;
memcpy(p->body, prop, len + 1);
old = lh_PROPERTY_DEFN_ELEM_insert(property_defns, p);
- if (old != NULL) {
- property_defn_free(old);
+ if (!ossl_assert(old == NULL))
+ /* This should not happen. An existing entry is handled above. */
goto end;
- }
if (!lh_PROPERTY_DEFN_ELEM_error(property_defns))
goto end;
}