}
#endif
+#ifndef FIPS_MODE
+static int init_thread_push_handlers(THREAD_EVENT_HANDLER **hands);
+static void init_thread_remove_handlers(THREAD_EVENT_HANDLER **handsin);
+static void init_thread_destructor(void *hands);
+static int init_thread_deregister(void *arg, int all);
+#endif
static void init_thread_stop(void *arg, THREAD_EVENT_HANDLER **hands);
static THREAD_EVENT_HANDLER **
if (alloc) {
if (hands == NULL) {
-#ifndef FIPS_MODE
- GLOBAL_TEVENT_REGISTER *gtr;
-#endif
- if ((hands = OPENSSL_zalloc(sizeof(*hands))) == NULL) {
- OPENSSL_free(hands);
+ if ((hands = OPENSSL_zalloc(sizeof(*hands))) == NULL)
return NULL;
- }
-#ifndef FIPS_MODE
- /*
- * The thread event handler is thread specific and is a linked
- * list of all handler functions that should be called for the
- * current thread. We also keep a global reference to that linked
- * list, so that we can deregister handlers if necessary before all
- * the threads are stopped.
- */
- gtr = get_global_tevent_register();
- if (gtr == NULL) {
+ if (!CRYPTO_THREAD_set_local(local, hands)) {
OPENSSL_free(hands);
return NULL;
}
- CRYPTO_THREAD_write_lock(gtr->lock);
- if (!sk_THREAD_EVENT_HANDLER_PTR_push(gtr->skhands, hands)) {
+
+#ifndef FIPS_MODE
+ if (!init_thread_push_handlers(hands)) {
+ CRYPTO_THREAD_set_local(local, NULL);
OPENSSL_free(hands);
- CRYPTO_THREAD_unlock(gtr->lock);
return NULL;
}
- CRYPTO_THREAD_unlock(gtr->lock);
#endif
- if (!CRYPTO_THREAD_set_local(local, hands)) {
- OPENSSL_free(hands);
- return NULL;
- }
}
} else if (!keep) {
CRYPTO_THREAD_set_local(local, NULL);
CRYPTO_THREAD_LOCAL value;
} destructor_key = { -1 };
+/*
+ * The thread event handler list is a thread specific linked list
+ * of callback functions which are invoked in list order by the
+ * current thread in case of certain events. (Currently, there is
+ * only one type of event, the 'thread stop' event.)
+ *
+ * We also keep a global reference to that linked list, so that we
+ * can deregister handlers if necessary before all the threads are
+ * stopped.
+ */
+static int init_thread_push_handlers(THREAD_EVENT_HANDLER **hands)
+{
+ int ret;
+ GLOBAL_TEVENT_REGISTER *gtr;
+
+ gtr = get_global_tevent_register();
+ if (gtr == NULL)
+ return 0;
+
+ CRYPTO_THREAD_write_lock(gtr->lock);
+ ret = (sk_THREAD_EVENT_HANDLER_PTR_push(gtr->skhands, hands) != 0);
+ CRYPTO_THREAD_unlock(gtr->lock);
+
+ return ret;
+}
+
static void init_thread_remove_handlers(THREAD_EVENT_HANDLER **handsin)
{
GLOBAL_TEVENT_REGISTER *gtr;
return 1;
}
-static int init_thread_deregister(void *arg, int all);
-
void ossl_cleanup_thread(void)
{
init_thread_deregister(NULL, 1);