commit 5629093afb1a64a305b4f4fd4b47a18eb05c1480 from: Stefan Sperling date: Mon Jul 11 11:19:43 2022 UTC make 'tog log' error out in shallow Git repositories instead of hanging ok op@ commit - 3c1dfe12b3f3eae6dc7ef4762772e849794296c5 commit + 5629093afb1a64a305b4f4fd4b47a18eb05c1480 blob - 310eb39a0776dd5fb11adc30d6c50fba6d7de13b blob + 87524f45815275ff098f65c61e350b793d15fe32 --- tog/tog.c +++ tog/tog.c @@ -337,6 +337,7 @@ struct tog_diff_view_state { }; pthread_mutex_t tog_mutex = PTHREAD_MUTEX_INITIALIZER; +static volatile sig_atomic_t tog_thread_error; struct tog_log_thread_args { pthread_cond_t need_commits; @@ -659,10 +660,10 @@ tog_fatal_signal_received(void) static const struct got_error * view_close(struct tog_view *view) { - const struct got_error *err = NULL; + const struct got_error *err = NULL, *child_err = NULL; if (view->child) { - view_close(view->child); + child_err = view_close(view->child); view->child = NULL; } if (view->close) @@ -672,7 +673,7 @@ view_close(struct tog_view *view) if (view->window) delwin(view->window); free(view); - return err; + return err ? err : child_err; } static struct tog_view * @@ -1489,7 +1490,8 @@ view_loop(struct tog_view *view) return err; update_panels(); doupdate(); - while (!TAILQ_EMPTY(&views) && !done && !tog_fatal_signal_received()) { + while (!TAILQ_EMPTY(&views) && !done && !tog_thread_error && + !tog_fatal_signal_received()) { /* Refresh fast during initialization, then become slower. */ if (fast_refresh && fast_refresh-- == 0) halfdelay(10); /* switch to once per second */ @@ -1590,9 +1592,12 @@ view_loop(struct tog_view *view) } done: while (!TAILQ_EMPTY(&views)) { + const struct got_error *close_err; view = TAILQ_FIRST(&views); TAILQ_REMOVE(&views, view, entry); - view_close(view); + close_err = view_close(view); + if (close_err && err == NULL) + err = close_err; } errcode = pthread_mutex_unlock(&tog_mutex); @@ -2328,10 +2333,8 @@ trigger_log_thread(struct tog_view *view, int wait) halfdelay(1); /* fast refresh while loading commits */ - while (ta->commits_needed > 0 || ta->load_all) { - if (ta->log_complete) - break; - + while (!ta->log_complete && !tog_thread_error && + (ta->commits_needed > 0 || ta->load_all)) { /* Wake the log thread. */ errcode = pthread_cond_signal(&ta->need_commits); if (errcode) @@ -2606,15 +2609,33 @@ log_thread(void *arg) struct tog_log_thread_args *a = arg; int done = 0; - err = block_signals_used_by_main_thread(); - if (err) + /* + * Sync startup with main thread such that we begin our + * work once view_input() has released the mutex. + */ + errcode = pthread_mutex_lock(&tog_mutex); + if (errcode) { + err = got_error_set_errno(errcode, "pthread_mutex_lock"); return (void *)err; + } + err = block_signals_used_by_main_thread(); + if (err) { + pthread_mutex_unlock(&tog_mutex); + goto done; + } + while (!done && !err && !tog_fatal_signal_received()) { + errcode = pthread_mutex_unlock(&tog_mutex); + if (errcode) { + err = got_error_set_errno(errcode, + "pthread_mutex_unlock"); + goto done; + } err = queue_commits(a); if (err) { if (err->code != GOT_ERR_ITER_COMPLETED) - return (void *)err; + goto done; err = NULL; done = 1; } else if (a->commits_needed > 0 && !a->load_all) @@ -2624,7 +2645,7 @@ log_thread(void *arg) if (errcode) { err = got_error_set_errno(errcode, "pthread_mutex_lock"); - break; + goto done; } else if (*a->quit) done = 1; else if (*a->first_displayed_entry == NULL) { @@ -2638,7 +2659,7 @@ log_thread(void *arg) err = got_error_set_errno(errcode, "pthread_cond_signal"); pthread_mutex_unlock(&tog_mutex); - break; + goto done; } if (done) @@ -2647,27 +2668,33 @@ log_thread(void *arg) if (a->commits_needed == 0 && !a->load_all) { errcode = pthread_cond_wait(&a->need_commits, &tog_mutex); - if (errcode) + if (errcode) { err = got_error_set_errno(errcode, "pthread_cond_wait"); + pthread_mutex_unlock(&tog_mutex); + goto done; + } if (*a->quit) done = 1; } } - - errcode = pthread_mutex_unlock(&tog_mutex); - if (errcode && err == NULL) - err = got_error_set_errno(errcode, - "pthread_mutex_unlock"); } a->log_complete = 1; + errcode = pthread_mutex_unlock(&tog_mutex); + if (errcode) + err = got_error_set_errno(errcode, "pthread_mutex_unlock"); +done: + if (err) { + tog_thread_error = 1; + pthread_cond_signal(&a->commit_loaded); + } return (void *)err; } static const struct got_error * stop_log_thread(struct tog_log_view_state *s) { - const struct got_error *err = NULL; + const struct got_error *err = NULL, *thread_err = NULL; int errcode; if (s->thread) { @@ -2680,7 +2707,7 @@ stop_log_thread(struct tog_log_view_state *s) if (errcode) return got_error_set_errno(errcode, "pthread_mutex_unlock"); - errcode = pthread_join(s->thread, (void **)&err); + errcode = pthread_join(s->thread, (void **)&thread_err); if (errcode) return got_error_set_errno(errcode, "pthread_join"); errcode = pthread_mutex_lock(&tog_mutex); @@ -2708,7 +2735,7 @@ stop_log_thread(struct tog_log_view_state *s) s->thread_args.graph = NULL; } - return err; + return err ? err : thread_err; } static const struct got_error *