* Return the EX_CALLBACKS from the |ex_data| array that corresponds to
* a given class. On success, *holds the lock.*
* The |global| parameter is assumed to be non null (checked by the caller).
+ * If |read| is 1 then a read lock is obtained. Otherwise it is a write lock.
*/
-static EX_CALLBACKS *get_and_lock(OSSL_EX_DATA_GLOBAL *global, int class_index)
+static EX_CALLBACKS *get_and_lock(OSSL_EX_DATA_GLOBAL *global, int class_index,
+ int read)
{
EX_CALLBACKS *ip;
return NULL;
}
- if (!CRYPTO_THREAD_write_lock(global->ex_data_lock))
- return NULL;
+ if (read) {
+ if (!CRYPTO_THREAD_read_lock(global->ex_data_lock))
+ return NULL;
+ } else {
+ if (!CRYPTO_THREAD_write_lock(global->ex_data_lock))
+ return NULL;
+ }
+
ip = &global->ex_data[class_index];
return ip;
}
if (global == NULL)
return 0;
- ip = get_and_lock(global, class_index);
+ ip = get_and_lock(global, class_index, 0);
if (ip == NULL)
return 0;
if (global == NULL)
return -1;
- ip = get_and_lock(global, class_index);
+ ip = get_and_lock(global, class_index, 0);
if (ip == NULL)
return -1;
if (global == NULL)
return 0;
- ip = get_and_lock(global, class_index);
+ ip = get_and_lock(global, class_index, 1);
if (ip == NULL)
return 0;
if (global == NULL)
return 0;
- ip = get_and_lock(global, class_index);
+ ip = get_and_lock(global, class_index, 1);
if (ip == NULL)
return 0;
if (global == NULL)
goto err;
- ip = get_and_lock(global, class_index);
+ ip = get_and_lock(global, class_index, 1);
if (ip == NULL)
goto err;
if (global == NULL)
return 0;
- ip = get_and_lock(global, class_index);
+ ip = get_and_lock(global, class_index, 1);
if (ip == NULL)
return 0;
f = sk_EX_CALLBACK_value(ip->meth, idx);