summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSamuel Thibault <samuel.thibault@ens-lyon.org>2023-11-26 21:01:49 +0100
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2023-11-26 21:01:49 +0100
commit5f25b24d6c6170cc366d9b71f99d741c4cfbc857 (patch)
tree38617ca12d24aa4f895948ad5fe26b1069776221
parent9e419ee8f47028e8f58c456b6456c348f7f0bcfa (diff)
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.
-rw-r--r--libports/manage-multithread.c13
1 files changed, 8 insertions, 5 deletions
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)
{