>From ed101ece64b645865779293eb48109cad03e9c35 Mon Sep 17 00:00:00 2001 From: Szabolcs Nagy Date: Sat, 9 Feb 2019 21:13:35 +0000 Subject: [PATCH] more robust synccall --- src/thread/synccall.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/thread/synccall.c b/src/thread/synccall.c index cc66bd24..7f275114 100644 --- a/src/thread/synccall.c +++ b/src/thread/synccall.c @@ -102,6 +102,7 @@ void __synccall(void (*func)(void *), void *ctx) /* Loop scanning the kernel-provided thread list until it shows no * threads that have not already replied to the signal. */ + int all_threads_caught = 0; for (;;) { int miss_cnt = 0; while ((de = readdir(&dir))) { @@ -120,6 +121,7 @@ void __synccall(void (*func)(void *), void *ctx) for (cp = head; cp && cp->tid != tid; cp=cp->next); if (cp) continue; + miss_cnt++; r = -__syscall(SYS_tgkill, pid, tid, SIGSYNCCALL); /* Target thread exit is a success condition. */ @@ -142,10 +144,16 @@ void __synccall(void (*func)(void *), void *ctx) /* Obtaining the lock means the thread responded. ESRCH * means the target thread exited, which is okay too. */ if (!r || r == ESRCH) continue; - - miss_cnt++; } - if (!miss_cnt) break; + if (miss_cnt) + all_threads_caught = 0; + else + all_threads_caught++; + /* when all visible threads are stopped there may be newly + * created threads that are not in dir yet, so only assume + * we are done when we see no running threads twice. */ + if (all_threads_caught > 1) + break; rewinddir(&dir); } close(dir.fd); -- 2.19.1