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

Reply via email to