commit f2d749db68f584041b421d0b6f6f3fb64251ff0c from: Stefan Sperling via: Thomas Adam date: Tue Jul 12 08:00:21 2022 UTC make 'tog log' error out in shallow Git repositories instead of hanging ok op@ commit - 0a046396cb50b910b505fbd85552af508f983fd8 commit + f2d749db68f584041b421d0b6f6f3fb64251ff0c blob - 2614f8dc8c70757784eb4751fbde9d831c3a9ef0 blob + 390a02baeb03b7162d8c778b7247f249c995114b --- tog/tog.c +++ tog/tog.c @@ -341,6 +341,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; @@ -663,10 +664,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) @@ -676,7 +677,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 * @@ -1493,7 +1494,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 */ @@ -1594,9 +1596,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); @@ -2332,10 +2337,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) @@ -2610,15 +2613,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) @@ -2628,7 +2649,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) { @@ -2642,7 +2663,7 @@ log_thread(void *arg) err = got_error_set_errno(errcode, "pthread_cond_signal"); pthread_mutex_unlock(&tog_mutex); - break; + goto done; } if (done) @@ -2651,27 +2672,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) { @@ -2684,7 +2711,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); @@ -2712,7 +2739,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 *