commit 33083b2ece357cee679ef84dea207a12302e4014 from: Mark Jamsek date: Wed Jan 22 05:53:11 2025 UTC tog: don't make users wait for the worktree diff to quit Reported by naddy: if the user opens tog and quickly quits before the log thread has finished fetching work tree state for displaying dirty work tree entries, the main thread waits for the log thread to finish before acting on the user's quit input. This produces a noticeable lag between entering 'q' and tog actually terminating. Pass a pointer to the quit flag to the worktree diff cancel callback so we can act on it immediately without making the user wait. tested by naddy who confirmed it greatly reduces the lag commit - 93d213ec350c9e74725a35816e23de4da87ea8f7 commit + 33083b2ece357cee679ef84dea207a12302e4014 blob - da3af395b2dbac57ee04e516108f32c3ee9ba1cd blob + 0ccc6a0f788f55d0c7f1bd60778f977402cfd4d8 --- tog/tog.c +++ tog/tog.c @@ -3140,7 +3140,15 @@ push_worktree_entry(struct tog_log_thread_args *ta, in static const struct got_error * check_cancelled(void *arg) { - if (tog_sigint_received || tog_sigpipe_received) + int rc, quit = 0; + + if ((rc = pthread_mutex_lock(&tog_mutex)) != 0) + return got_error_set_errno(rc, "pthread_mutex_lock"); + if (tog_sigint_received || tog_sigpipe_received || *((int *)arg)) + quit = 1; + if ((rc = pthread_mutex_unlock(&tog_mutex)) != 0) + return got_error_set_errno(rc, "pthread_mutex_unlock"); + if (quit) return got_error(GOT_ERR_CANCELLED); return NULL; } @@ -3212,12 +3220,9 @@ tog_worktree_status(struct tog_log_thread_args *ta) goto done; err = got_worktree_status(wt, &paths, ta->repo, 0, - check_local_changes, &wt_state, check_cancelled, NULL); - if (err != NULL) { - if (err->code != GOT_ERR_CANCELLED) - goto done; - err = NULL; - } + check_local_changes, &wt_state, check_cancelled, ta->quit); + if (err != NULL) + goto done; if (wt_state != 0) { err = get_author(&wctx->wt_author, ta->repo, wt); @@ -4049,8 +4054,11 @@ log_thread(void *arg) goto done; } err = tog_worktree_status(a); - if (err != NULL) + if (err != NULL) { + if (err->code == GOT_ERR_CANCELLED) + err = NULL; goto done; + } errcode = pthread_mutex_lock(&tog_mutex); if (errcode) { err = got_error_set_errno(errcode,