From 5f25b24d6c6170cc366d9b71f99d741c4cfbc857 Mon Sep 17 00:00:00 2001 From: Samuel Thibault Date: Sun, 26 Nov 2023 21:01:49 +0100 Subject: libports: Force threads to wake up periodically Quiescence support in port-deref-deferred.c assumes that all threads will sooner or later go through a quiescent state (because it finished processing a message). But that is not true: proc doesn't set a thread timeout, and thus some threads can stay indefinitely stuck in receiving messages. And thus the deferred dereferencing used by ports_destroy_right never gets achieved. This accumulation can be seen by running: while true ; do echo $(echo -n $(echo a)) > /dev/null ; done while running vminfo 4 | wc -l in parallel. Making threads get out of mach_msg at least periodically allows unstucking quiescence generations. --- libports/manage-multithread.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) (limited to 'libports') diff --git a/libports/manage-multithread.c b/libports/manage-multithread.c index 9c036911..62f5c4e7 100644 --- a/libports/manage-multithread.c +++ b/libports/manage-multithread.c @@ -256,11 +256,14 @@ ports_manage_port_operations_multithread (struct port_bucket *bucket, startover: do - err = mach_msg_server_timeout (synchronized_demuxer, - 0, bucket->portset, - timeout ? MACH_RCV_TIMEOUT : 0, - timeout); - while (err != MACH_RCV_TIMED_OUT); + { + err = mach_msg_server_timeout (synchronized_demuxer, + 0, bucket->portset, + MACH_RCV_TIMEOUT, + timeout ? timeout : 10 * 1000); + _ports_thread_quiescent (&bucket->threadpool, &thread); + } + while (!(timeout && err == MACH_RCV_TIMED_OUT)); if (master) { -- cgit v1.2.3