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;
}
Modules
- AABB3D
- ACCEPT_POOL
- ALLEGRO4
- ALLEGRO5
- ANIM_LIB
- ASTAR
- ATLAS_LIB
- AVRO
- CLOCK_SYNC
- COMMONS
- CONFIGFILE
- CYPHER_BASE64
- CYPHER_VIGENERE
- DEAD_RECKONING
- ENUMS
- EXCEPTIONS
- GAME_ENV
- GIT
- GUI
- HASH_TABLE
- ISOMETRIC_ENGINE
- LIST
- LOG
- LOGNODUP
- LZ4
- NETWORKING
- NETWORK_MSG
- N_COOKIES
- N_DIFF
- N_DIGEST
- N_DISK_CACHE
- N_DNS
- N_ECC
- N_ENTROPY
- N_FILES
- N_FLUIDS
- N_GUI_COLOR
- N_GUI_COLORWHEEL
- N_GUI_CURVE
- N_GUI_GRID
- N_GUI_POPUP
- N_HEX
- N_HTTP3
- N_HTTP_COOKIE
- N_HTTP_FORM
- N_HTTP_MIME
- N_HTTP_REQ
- N_HTTP_RESP
- N_HTTP_ROUTER
- N_HTTP_SERVER
- N_ICC
- N_JSON
- N_KAFKA
- N_LINALG
- N_MODULE
- N_OPENSSL_COMPAT
- N_PRETTY
- N_PTH
- N_QUERY
- N_RANDOM
- N_SHA256
- N_STR
- N_TIFF
- N_TIME
- N_USER
- N_X509
- N_ZIP
- PARTICLES
- PCRE
- PHYSICS
- SIGNALS
- STACK
- THREADS
- TRAJECTORY
- TREE
- ZLIB