run-command: use thread-aware die_is_recursing routine

If we die from an async thread, we do not actually exit the
program, but just kill the thread. This confuses the static
counter in usage.c's default die_is_recursing function; it
updates the counter once for the thread death, and then when
the main program calls die() itself, it erroneously thinks
we are recursing. The end result is that we print "recursion
detected in die handler" instead of the real error in such a
case (the easiest way to trigger this is having a remote
connection hang up while running a sideband demultiplexer).

This patch solves it by using a per-thread counter when the
async_die function is installed; we detect recursion in each
thread (including the main one), but they do not step on
each other's toes.

Other threaded code does not need to worry about this, as
they do not install specialized die handlers; they just let
a die() from a sub-thread take down the whole program.

Since we are overriding the default recursion-check
function, there is an interesting corner case that is not a
problem, but bears some explanation. Imagine the main thread
calls die(), and then in the die_routine starts an async
call. We will switch to using thread-local storage, which
starts at 0, for the main thread's counter, even though
the original counter was actually at 1. That's OK, though,
for two reasons:

  1. It would miss only the first level of recursion, and
     would still find recursive failures inside the async
     helper.

  2. We do not currently and are not likely to start doing
     anything as heavyweight as starting an async routine
     from within a die routine or helper function.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 file changed
tree: 5b67788dbf4e6e819cd562c0eb2414bd39c51287
  1. block-sha1/
  2. builtin/
  3. compat/
  4. contrib/
  5. Documentation/
  6. git-gui/
  7. git_remote_helpers/
  8. gitk-git/
  9. gitweb/
  10. mergetools/
  11. perl/
  12. po/
  13. ppc/
  14. t/
  15. templates/
  16. vcs-svn/
  17. xdiff/
  18. .gitattributes
  19. .gitignore
  20. .mailmap
  21. abspath.c
  22. aclocal.m4
  23. advice.c
  24. advice.h
  25. alias.c
  26. alloc.c
  27. archive-tar.c
  28. archive-zip.c
  29. archive.c
  30. archive.h
  31. argv-array.c
  32. argv-array.h
  33. attr.c
  34. attr.h
  35. base85.c
  36. bisect.c
  37. bisect.h
  38. blob.c
  39. blob.h
  40. branch.c
  41. branch.h
  42. builtin.h
  43. bulk-checkin.c
  44. bulk-checkin.h
  45. bundle.c
  46. bundle.h
  47. cache-tree.c
  48. cache-tree.h
  49. cache.h
  50. check-builtins.sh
  51. check-racy.c
  52. check_bindir
  53. color.c
  54. color.h
  55. column.c
  56. column.h
  57. combine-diff.c
  58. command-list.txt
  59. commit.c
  60. commit.h
  61. config.c
  62. config.mak.in
  63. configure.ac
  64. connect.c
  65. connected.c
  66. connected.h
  67. convert.c
  68. convert.h
  69. copy.c
  70. COPYING
  71. credential-cache--daemon.c
  72. credential-cache.c
  73. credential-store.c
  74. credential.c
  75. credential.h
  76. csum-file.c
  77. csum-file.h
  78. ctype.c
  79. daemon.c
  80. date.c
  81. decorate.c
  82. decorate.h
  83. delta.h
  84. diff-delta.c
  85. diff-lib.c
  86. diff-no-index.c
  87. diff.c
  88. diff.h
  89. diffcore-break.c
  90. diffcore-delta.c
  91. diffcore-order.c
  92. diffcore-pickaxe.c
  93. diffcore-rename.c
  94. diffcore.h
  95. dir.c
  96. dir.h
  97. editor.c
  98. entry.c
  99. environment.c
  100. exec_cmd.c
  101. exec_cmd.h
  102. fast-import.c
  103. fetch-pack.c
  104. fetch-pack.h
  105. fixup-builtins
  106. fmt-merge-msg.h
  107. fsck.c
  108. fsck.h
  109. generate-cmdlist.sh
  110. gettext.c
  111. gettext.h
  112. git-add--interactive.perl
  113. git-am.sh
  114. git-archimport.perl
  115. git-bisect.sh
  116. git-compat-util.h
  117. git-cvsexportcommit.perl
  118. git-cvsimport.perl
  119. git-cvsserver.perl
  120. git-difftool--helper.sh
  121. git-difftool.perl
  122. git-filter-branch.sh
  123. git-instaweb.sh
  124. git-lost-found.sh
  125. git-merge-octopus.sh
  126. git-merge-one-file.sh
  127. git-merge-resolve.sh
  128. git-mergetool--lib.sh
  129. git-mergetool.sh
  130. git-p4.py
  131. git-parse-remote.sh
  132. git-pull.sh
  133. git-quiltimport.sh
  134. git-rebase--am.sh
  135. git-rebase--interactive.sh
  136. git-rebase--merge.sh
  137. git-rebase.sh
  138. git-relink.perl
  139. git-remote-testgit.py
  140. git-repack.sh
  141. git-request-pull.sh
  142. git-send-email.perl
  143. git-sh-i18n.sh
  144. git-sh-setup.sh
  145. git-stash.sh
  146. git-submodule.sh
  147. git-svn.perl
  148. GIT-VERSION-GEN
  149. git-web--browse.sh
  150. git.c
  151. git.spec.in
  152. gpg-interface.c
  153. gpg-interface.h
  154. graph.c
  155. graph.h
  156. grep.c
  157. grep.h
  158. hash.c
  159. hash.h
  160. help.c
  161. help.h
  162. hex.c
  163. http-backend.c
  164. http-fetch.c
  165. http-push.c
  166. http-walker.c
  167. http.c
  168. http.h
  169. ident.c
  170. imap-send.c
  171. INSTALL
  172. kwset.c
  173. kwset.h
  174. levenshtein.c
  175. levenshtein.h
  176. LGPL-2.1
  177. list-objects.c
  178. list-objects.h
  179. ll-merge.c
  180. ll-merge.h
  181. lockfile.c
  182. log-tree.c
  183. log-tree.h
  184. mailmap.c
  185. mailmap.h
  186. Makefile
  187. match-trees.c
  188. merge-blobs.c
  189. merge-blobs.h
  190. merge-recursive.c
  191. merge-recursive.h
  192. merge.c
  193. mergesort.c
  194. mergesort.h
  195. name-hash.c
  196. notes-cache.c
  197. notes-cache.h
  198. notes-merge.c
  199. notes-merge.h
  200. notes.c
  201. notes.h
  202. object.c
  203. object.h
  204. pack-check.c
  205. pack-refs.c
  206. pack-refs.h
  207. pack-revindex.c
  208. pack-revindex.h
  209. pack-write.c
  210. pack.h
  211. pager.c
  212. parse-options-cb.c
  213. parse-options.c
  214. parse-options.h
  215. patch-delta.c
  216. patch-ids.c
  217. patch-ids.h
  218. path.c
  219. pkt-line.c
  220. pkt-line.h
  221. preload-index.c
  222. pretty.c
  223. progress.c
  224. progress.h
  225. prompt.c
  226. prompt.h
  227. quote.c
  228. quote.h
  229. reachable.c
  230. reachable.h
  231. read-cache.c
  232. README
  233. reflog-walk.c
  234. reflog-walk.h
  235. refs.c
  236. refs.h
  237. remote-curl.c
  238. remote-testsvn.c
  239. remote.c
  240. remote.h
  241. replace_object.c
  242. rerere.c
  243. rerere.h
  244. resolve-undo.c
  245. resolve-undo.h
  246. revision.c
  247. revision.h
  248. run-command.c
  249. run-command.h
  250. send-pack.c
  251. send-pack.h
  252. sequencer.c
  253. sequencer.h
  254. server-info.c
  255. setup.c
  256. sh-i18n--envsubst.c
  257. sha1-array.c
  258. sha1-array.h
  259. sha1-lookup.c
  260. sha1-lookup.h
  261. sha1_file.c
  262. sha1_name.c
  263. shallow.c
  264. shell.c
  265. shortlog.h
  266. show-index.c
  267. sideband.c
  268. sideband.h
  269. sigchain.c
  270. sigchain.h
  271. strbuf.c
  272. strbuf.h
  273. streaming.c
  274. streaming.h
  275. string-list.c
  276. string-list.h
  277. submodule.c
  278. submodule.h
  279. symlinks.c
  280. tag.c
  281. tag.h
  282. tar.h
  283. test-chmtime.c
  284. test-ctype.c
  285. test-date.c
  286. test-delta.c
  287. test-dump-cache-tree.c
  288. test-genrandom.c
  289. test-index-version.c
  290. test-line-buffer.c
  291. test-match-trees.c
  292. test-mergesort.c
  293. test-mktemp.c
  294. test-parse-options.c
  295. test-path-utils.c
  296. test-regex.c
  297. test-revision-walking.c
  298. test-run-command.c
  299. test-scrap-cache-tree.c
  300. test-sha1.c
  301. test-sha1.sh
  302. test-sigchain.c
  303. test-string-list.c
  304. test-subprocess.c
  305. test-svn-fe.c
  306. thread-utils.c
  307. thread-utils.h
  308. trace.c
  309. transport-helper.c
  310. transport.c
  311. transport.h
  312. tree-diff.c
  313. tree-walk.c
  314. tree-walk.h
  315. tree.c
  316. tree.h
  317. unimplemented.sh
  318. unix-socket.c
  319. unix-socket.h
  320. unpack-trees.c
  321. unpack-trees.h
  322. upload-pack.c
  323. url.c
  324. url.h
  325. usage.c
  326. userdiff.c
  327. userdiff.h
  328. utf8.c
  329. utf8.h
  330. varint.c
  331. varint.h
  332. version.c
  333. version.h
  334. walker.c
  335. walker.h
  336. wrap-for-bin.sh
  337. wrapper.c
  338. write_or_die.c
  339. ws.c
  340. wt-status.c
  341. wt-status.h
  342. xdiff-interface.c
  343. xdiff-interface.h
  344. zlib.c