return -1;
}
}
-
- /*
- * If we're threaded, check if the module is thread-safe.
- *
- * If it isn't, we init the mutex.
- */
- if ((mi->module->type & MODULE_TYPE_THREAD_UNSAFE) != 0) pthread_mutex_init(&mi->mutex, NULL);
mi->state = MODULE_INSTANCE_INSTANTIATED;
return 0;
*/
if (mi->module && ((mi->module->type & MODULE_TYPE_THREAD_UNSAFE) != 0)) {
#ifndef NDEBUG
+ int ret;
+
/*
* If the mutex is locked that means
* the server exited without cleaning
*
* Assert that the mutex is not held.
*/
- fr_assert(pthread_mutex_trylock(&mi->mutex) == 0);
+ fr_assert_msg((ret = pthread_mutex_trylock(&mi->mutex)) == 0,
+ "Failed locking module mutex during exit: %s", fr_syserror(ret));
pthread_mutex_unlock(&mi->mutex);
#endif
pthread_mutex_destroy(&mi->mutex);
}
MEM(mi = talloc_zero(parent ? (void const *)parent : (void const *)ml, module_instance_t));
+ /*
+ * If we're threaded, check if the module is thread-safe.
+ *
+ * If it isn't, we init the mutex.
+ *
+ * Do this here so the destructor can trylock the mutex
+ * correctly even if bootstrap/instantiation fails.
+ */
+ if ((mi->module->type & MODULE_TYPE_THREAD_UNSAFE) != 0) pthread_mutex_init(&mi->mutex, NULL);
talloc_set_destructor(mi, _module_instance_free);
if (dl_module_instance(mi, &mi->dl_inst, parent ? parent->dl_inst : NULL,