commit 472bdb824c6e30d0d7becab2a826f6a13bffb384 from: Mark Jamsek via: Thomas Adam date: Fri Jan 24 22:02:34 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 - acca3e784b8d3ba91774e39aa50d325db895b434 commit + 472bdb824c6e30d0d7becab2a826f6a13bffb384 blob - a5a632533613cb01b96fee51cdd4d7033964b7e2 blob + eeeaf674438fcb6535713a5673c82658840f9501 --- tog/tog.c +++ tog/tog.c @@ -3143,7 +3143,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; } @@ -3215,12 +3223,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); @@ -4052,8 +4057,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,