6 ex__thread__pool__wait_8c
gullradriel edited this page 2026-10-09 00:55:18 +02:00

examples/ex_thread_pool_wait.c

wait_for_threaded_pool must return when a proc that was STILL RUNNING at the moment of the call finishes. More...

Functions

Name
void * slow_proc(void * p)
int main(void )

Detailed Description

wait_for_threaded_pool must return when a proc that was STILL RUNNING at the moment of the call finishes.

Author: Castagnier Mickael

Version: 1.0

That ordering is the one that used to strand the caller: the idle token is posted by refresh_thread_pool only, and the post was guarded by reading sem_getvalue, whose result POSIX leaves unspecified while a thread is blocked in sem_wait. Where that read is not zero for a blocked waiter (winpthreads reports a negative waiter count) the post was skipped and the waiter never woke. glibc reports zero, so this passes on Linux either way; it is a guard against reintroducing the dependency, and it fails outright anywhere the value differs.

Functions Documentation

function slow_proc

static void * slow_proc(
    void * p
)

function main

int main(
    void 
)

Source code

/*
 * Nilorea Library
 * Copyright (C) 2005-2026 Castagnier Mickael
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include "nilorea/n_common.h"
#include "nilorea/n_log.h"
#include "nilorea/n_thread_pool.h"

#include <stdio.h>
#include <unistd.h>

static void* slow_proc(void* p) {
    (void)p;
    usleep(1500000); /* 1.5 s, as a real audit request against a remote host */
    return NULL;
}

int main(void) {
    set_log_level(LOG_ERR);
    /* one active thread, no waiting slots: exactly what the scanner builds for a
       single-endpoint audit (new_thread_pool(nthr, 0) with nthr == 1) */
    THREAD_POOL* pool = new_thread_pool(1, 0);
    if (!pool) {
        printf("FAIL: no pool\n");
        return 1;
    }
    if (add_threaded_process(pool, &slow_proc, NULL, NORMAL_PROC) == FALSE) {
        printf("FAIL: could not add proc\n");
        return 1;
    }
    wait_for_threaded_pool(pool); /* hung here before the fix */
    destroy_threaded_pool(&pool, 1000);
    printf("ex_thread_pool_wait: all checks passed\n");
    return 0;
}