diff --git a/common/git/kicad_git_common.cpp b/common/git/kicad_git_common.cpp index 7d3d7fe622..3fc04266a8 100644 --- a/common/git/kicad_git_common.cpp +++ b/common/git/kicad_git_common.cpp @@ -258,7 +258,7 @@ std::pair,std::set> KIGIT_COMMON::GetDifferentFiles std::set 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> 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> KIGIT_COMMON::GetDifferentFiles std::pair,std::set> modified_files; - if( !m_repo ) + if( !m_repo || IsCancelled() ) return modified_files; git_reference* head = nullptr; diff --git a/common/git/kicad_git_common.h b/common/git/kicad_git_common.h index 93262852b5..7780cd2dde 100644 --- a/common/git/kicad_git_common.h +++ b/common/git/kicad_git_common.h @@ -26,6 +26,7 @@ #include +#include #include #include #include @@ -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 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 ); diff --git a/kicad/project_tree_pane.cpp b/kicad/project_tree_pane.cpp index 7a9aad0ad9..99a81d1c9b 100644 --- a/kicad/project_tree_pane.cpp +++ b/kicad/project_tree_pane.cpp @@ -2133,6 +2133,21 @@ void PROJECT_TREE_PANE::updateGitStatusIconMap() return; } + std::unique_lock 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();