When we have started threads with the async subsystem, both
the thread and the main program may call die(). The async
subsystem sets up a special die routine to call pthread_exit
rather than regular exit, but the recursion check in die()
happens outside of this routine, and does not know that it's
OK for two dies to run.

As a result, we may print "recursion in die handler" when an
async thread dies, even though there is no recursion. This
can be triggered, for example, by upload-pack errors; the
receiving side will die both in the async sideband
demultiplexer and in the main program.

This patch teaches the recursion check to use the same
running_main_thread() check that the async code bases its
exit decision on. That means we detect only recursion within
the main program itself, and assume that async handlers
correctly die (which they do).

Signed-off-by: Jeff King <p...@peff.net>
This is the simplest solution. You could actually have a thread-local
dying counter, which would detect die recursion within an async thread.
But I did not want to get into designing a lowest-common-denominator of
thread-local storage that would work on all of our platforms.

 usage.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/usage.c b/usage.c
index c6b7ac5..33405c8 100644
--- a/usage.c
+++ b/usage.c
@@ -5,6 +5,7 @@
 #include "git-compat-util.h"
 #include "cache.h"
+#include "run-command.h"
 void vreportf(const char *prefix, const char *err, va_list params)
@@ -82,6 +83,9 @@ static void check_die_recursion(const char *fmt, va_list ap)
        static int dying;
+       if (!running_main_thread())
+               return;
        if (!dying++)
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to