Handle git cancellation when closing

Tidies up a few places where we need to hold the mutex and early exit
from loops if we are quitting

Fixes https://gitlab.com/kicad/code/kicad/-/issues/21849

(cherry picked from commit fd2ddf60b7)
This commit is contained in:
Seth Hillbrand
2025-12-29 08:51:15 -08:00
parent 19a9cac436
commit 04ea0796d0
3 changed files with 47 additions and 5 deletions
+6 -2
View File
@@ -258,7 +258,7 @@ std::pair<std::set<wxString>,std::set<wxString>> KIGIT_COMMON::GetDifferentFiles
std::set<wxString> modified_set;
git_revwalk* walker = nullptr;
if( !m_repo || !from_oid )
if( !m_repo || !from_oid || IsCancelled() )
return modified_set;
if( git_revwalk_new( &walker, m_repo ) != GIT_OK )
@@ -286,6 +286,10 @@ std::pair<std::set<wxString>,std::set<wxString>> KIGIT_COMMON::GetDifferentFiles
// iterate over all local commits not in remote
while( git_revwalk_next( &oid, walker ) == GIT_OK )
{
// Check for cancellation to allow early exit during shutdown
if( IsCancelled() )
return modified_set;
if( git_commit_lookup( &commit, m_repo, &oid ) != GIT_OK )
{
wxLogTrace( traceGit, "Failed to lookup commit: %s", KIGIT_COMMON::GetLastGitError() );
@@ -371,7 +375,7 @@ std::pair<std::set<wxString>,std::set<wxString>> KIGIT_COMMON::GetDifferentFiles
std::pair<std::set<wxString>,std::set<wxString>> modified_files;
if( !m_repo )
if( !m_repo || IsCancelled() )
return modified_files;
git_reference* head = nullptr;
+9
View File
@@ -26,6 +26,7 @@
#include <git/kicad_git_errors.h>
#include <atomic>
#include <git2.h>
#include <mutex>
#include <set>
@@ -138,6 +139,12 @@ public:
int HandleSSHAgentAuthentication( git_cred** aOut, const wxString& aUsername );
bool IsCancelled() const { return m_cancel.load(); }
void SetCancelled( bool aCancel ) { m_cancel.store( aCancel ); }
std::mutex& GetMutex() { return m_gitActionMutex; }
static wxString GetLastGitError()
{
const git_error* error = git_error_last();
@@ -174,6 +181,8 @@ private:
int m_nextPublicKey;
bool m_secretFetched;
std::atomic<bool> m_cancel{ false };
// Create a dummy flag to tell if we have tested ssh agent credentials separately
// from the ssh key credentials
static const unsigned KIGIT_CREDENTIAL_SSH_AGENT = 1 << sizeof( m_testedTypes - 1 );
+32 -3
View File
@@ -2133,6 +2133,21 @@ void PROJECT_TREE_PANE::updateGitStatusIconMap()
return;
}
std::unique_lock<std::mutex> gitLock( m_TreeProject->GitCommon()->GetMutex(),
std::try_to_lock );
if( !gitLock.owns_lock() )
{
wxLogTrace( traceGit, wxS( "updateGitStatusIconMap: Failed to acquire git action mutex" ) );
return;
}
if( m_TreeProject->GitCommon()->IsCancelled() )
{
wxLogTrace( traceGit, wxS( "updateGitStatusIconMap: Cancelled" ) );
return;
}
// Get Current Branch
wxFileName rootFilename( Prj().GetProjectFullName() );
wxString repoWorkDir( git_repository_workdir( repo ) );
@@ -2726,13 +2741,22 @@ void PROJECT_TREE_PANE::onGitSyncTimer( wxTimerEvent& aEvent )
return;
}
if( gitCommon->IsCancelled() )
{
wxLogTrace( traceGit, "onGitSyncTimer: Cancelled" );
return;
}
GIT_PULL_HANDLER handler( gitCommon );
handler.PerformFetch();
CallAfter( [this]()
if( !gitCommon->IsCancelled() )
{
gitStatusTimerHandler();
} );
CallAfter( [this]()
{
gitStatusTimerHandler();
} );
}
} );
if( gitSettings.updatInterval > 0 )
@@ -2746,6 +2770,11 @@ void PROJECT_TREE_PANE::onGitSyncTimer( wxTimerEvent& aEvent )
void PROJECT_TREE_PANE::gitStatusTimerHandler()
{
KIGIT_COMMON* gitCommon = m_TreeProject ? m_TreeProject->GitCommon() : nullptr;
if( !gitCommon || gitCommon->IsCancelled() )
return;
updateTreeCache();
thread_pool& tp = GetKiCadThreadPool();