caerModuleData caerModuleInitialize(uint16_t moduleID, const char *moduleShortName, sshsNode mainloopNode) { // Generate short module name with ID, reused in all error messages and later code. size_t nameLength = (size_t) snprintf(NULL, 0, "%" PRIu16 "-%s", moduleID, moduleShortName); char nameString[nameLength + 1]; snprintf(nameString, nameLength + 1, "%" PRIu16 "-%s", moduleID, moduleShortName); // Allocate memory for the module. caerModuleData moduleData = calloc(1, sizeof(struct caer_module_data)); if (moduleData == NULL) { caerLog(CAER_LOG_ALERT, nameString, "Failed to allocate memory for module. Error: %d.", errno); thrd_exit(EXIT_FAILURE); } // Set module ID for later identification (hash-table key). moduleData->moduleID = moduleID; // Put module into startup state. moduleData->moduleStatus = STOPPED; atomic_store_explicit(&moduleData->running, true, memory_order_relaxed); // Determine SSHS module node. Use short name for better human recognition. char sshsString[nameLength + 2]; strncpy(sshsString, nameString, nameLength); sshsString[nameLength] = '/'; sshsString[nameLength + 1] = '\0'; // Initialize configuration, shutdown hooks. moduleData->moduleNode = sshsGetRelativeNode(mainloopNode, sshsString); if (moduleData->moduleNode == NULL) { caerLog(CAER_LOG_ALERT, nameString, "Failed to allocate configuration node for module."); thrd_exit(EXIT_FAILURE); } sshsNodePutBool(moduleData->moduleNode, "shutdown", false); // Always reset to false. sshsNodeAddAttributeListener(moduleData->moduleNode, moduleData, &caerModuleShutdownListener); // Setup default full log string name. moduleData->moduleSubSystemString = malloc(nameLength + 1); if (moduleData->moduleSubSystemString == NULL) { caerLog(CAER_LOG_ALERT, nameString, "Failed to allocate subsystem string for module."); thrd_exit(EXIT_FAILURE); } strncpy(moduleData->moduleSubSystemString, nameString, nameLength); moduleData->moduleSubSystemString[nameLength] = '\0'; atomic_thread_fence(memory_order_release); return (moduleData); }
void randomdev_unblock(void) { #if 0 if (mtx_trylock(&random_reseed_mtx) == thrd_busy) printf("Mutex held. Good.\n"); else { printf("Mutex not held. PANIC!!\n"); thrd_exit(0); } #endif printf("random: unblocking device.\n"); }
static int tss_thrd (void *arg) { if (tss_create (&key, NULL) != thrd_success) FAIL_EXIT1 ("tss_create failed"); if (tss_set (key, TSS_VALUE)) FAIL_EXIT1 ("tss_set failed"); void *value = tss_get (key); if (value == 0) FAIL_EXIT1 ("tss_get failed"); if (value != TSS_VALUE) FAIL_EXIT1 ("tss_get returned %p, expected %p", value, TSS_VALUE); thrd_exit (thrd_success); }
/** * @brief Yield execution back to the main thread * @protected * * This function may only be called inside the processing thread * spawned for thread-based plugins. * * @param stream The stream * @param status Status code to return for the current request * @return The code of the next requested operation */ static SquashOperation squash_stream_yield (SquashStream* stream, SquashStatus status) { SquashStreamPrivate* priv = stream->priv; SquashOperation operation; assert (stream != NULL); assert (priv != NULL); priv->request = SQUASH_OPERATION_INVALID; priv->result = status; cnd_signal (&(priv->result_cnd)); mtx_unlock (&(priv->io_mtx)); if (status < 0) thrd_exit (status); mtx_lock (&(priv->io_mtx)); while ((operation = priv->request) == SQUASH_OPERATION_INVALID) { cnd_wait (&(priv->request_cnd), &(priv->io_mtx)); } return operation; }
void ThreadAPI_Exit(int res) { thrd_exit(res); }
static int test_thrd_exit_func(void* arg) { test_sleep(); thrd_exit(2); return 1; }