On Tue, 10 Nov 2026 20:13:46 Samuel Thibault wrote:
> > I forgot to ask: in pager_start_workers, we create threads, but if
an error
> > occurs, we don’t do anything with them. Perhaps we should
terminate them
> > first, and only then free the memory?
>
> Indeed. It should be fine enough to pthread_cancel + pthread_join them.
I think we can factor this out, and if an issue arises while creating
threads, we’ll be able to cancel the ones that have already been started.
Thanks,
--
Mikhail Karpov
From b4ed37d919e9585ac038f4160c983769f4b898bd Mon Sep 17 00:00:00 2001
From: Mikhail Karpov <[email protected]>
Date: Wed, 11 Nov 2026 12:25:29 +0700
Subject: [PATCH 3/3] Canceling threads in the event of failure during their
creation in pager_start_workers
---
libpager/demuxer.c | 27 ++++++++++++++++++++-------
1 file changed, 20 insertions(+), 7 deletions(-)
diff --git a/libpager/demuxer.c b/libpager/demuxer.c
index c649700..9040c2d 100644
--- a/libpager/demuxer.c
+++ b/libpager/demuxer.c
@@ -316,8 +316,9 @@ pager_start_workers (struct port_bucket *pager_bucket,
struct pager_requests **out_requests)
{
error_t err;
- int i;
- pthread_t t;
+ size_t i;
+ pthread_t service_paging_pthread;
+ pthread_t worker_pthreads[WORKER_COUNT];
struct pager_requests *requests;
struct rlimit limits = { RLIM_INFINITY, RLIM_INFINITY };
@@ -352,10 +353,11 @@ pager_start_workers (struct port_bucket *pager_bucket,
pthread_mutex_init (&requests->lock, NULL);
/* Make a thread to service paging requests. */
- err = pthread_create (&t, NULL, service_paging_requests, requests);
+ err = pthread_create (&service_paging_pthread, NULL,
+ service_paging_requests, requests);
if (err)
goto free_queue;
- pthread_detach (t);
+ pthread_detach (service_paging_pthread);
for (i = 0; i < WORKER_COUNT; i++)
{
@@ -363,15 +365,26 @@ pager_start_workers (struct port_bucket *pager_bucket,
requests->workers[i].tag = 0;
queue_init (&requests->workers[i].queue);
- err = pthread_create (&t, NULL, &worker_func, &requests->workers[i]);
+ err = pthread_create (&worker_pthreads[i], NULL, &worker_func,
+ &requests->workers[i]);
if (err)
- goto free_queue;
- pthread_detach (t);
+ goto pthreads_cancel;
+ pthread_detach (worker_pthreads[i]);
}
*out_requests = requests;
return 0;
+ pthreads_cancel:
+ for (size_t j = 0; j < i; ++j)
+ {
+ pthread_cancel (worker_pthreads[j]);
+ pthread_join (worker_pthreads[j], NULL);
+ }
+
+ pthread_cancel (service_paging_pthread);
+ pthread_join (service_paging_pthread, NULL);
+
free_queue:
free (requests->queue_in);
--
2.43.0