KiCad PCB EDA Suite
Loading...
Searching...
No Matches
HISTORY_LOCK_MANAGER Class Reference

Hybrid locking mechanism for local history git repositories. More...

#include <history_lock.h>

Public Member Functions

 HISTORY_LOCK_MANAGER (const wxString &aProjectPath, int aStaleTimeoutSec=0)
 Construct a lock manager and attempt to acquire locks.
 
 HISTORY_LOCK_MANAGER (const wxString &aProjectPath, const wxString &aHistoryPath, int aStaleTimeoutSec=0)
 As above, with the history directory already resolved.
 
 ~HISTORY_LOCK_MANAGER ()
 Destructor releases all locks and closes git repository.
 
 HISTORY_LOCK_MANAGER (const HISTORY_LOCK_MANAGER &)=delete
 
HISTORY_LOCK_MANAGER & operator= (const HISTORY_LOCK_MANAGER &)=delete
 
bool IsLocked () const
 Check if locks were successfully acquired.
 
git_repository * GetRepository ()
 Get the git repository handle (only valid if IsLocked() returns true).
 
git_index * GetIndex ()
 Get the git index handle (only valid if IsLocked() returns true).
 
wxString GetLockError () const
 Get error message describing why lock could not be acquired.
 
wxString GetLockHolder () const
 Get information about who currently holds the lock.
 
void ReleaseRepository ()
 Release git repository and index handles early, but keep the file lock.
 
git_repository * ReopenRepository ()
 Re-open the git repository and index after ReleaseRepository().
 

Static Public Member Functions

static bool IsLockStale (const wxString &aProjectPath, int aStaleTimeoutSec=0)
 Check if a lock file exists and is stale (older than timeout).
 
static bool BreakStaleLock (const wxString &aProjectPath)
 Claim and remove an abandoned lock belonging to this user.
 

Private Member Functions

bool acquireFileLock ()
 
bool openRepository ()
 
bool acquireIndexLock ()
 

Private Attributes

wxString m_projectPath
 
wxString m_historyPath
 
std::unique_ptr< LOCKFILE > m_fileLock
 
git_repository * m_repo
 
git_index * m_index
 
bool m_repoOwned
 
bool m_indexOwned
 
wxString m_lockError
 
int m_staleTimeoutSec
 

Detailed Description

Hybrid locking mechanism for local history git repositories.

Implements a two-layer locking strategy:

  • Layer 1: File-based lock (prevents cross-instance conflicts)
  • Layer 2: Git index lock (prevents concurrent git operations)

This provides defense-in-depth protection against:

  • Multiple KiCad instances accessing same project
  • Multi-threaded operations within same instance
  • Repository corruption from concurrent writes

Usage:

HISTORY_LOCK_MANAGER lock( projectPath );
if( !lock.IsLocked() )
{
wxLogError( "Cannot acquire lock: %s", lock.GetLockError() );
return false;
}
git_repository* repo = lock.GetRepository();
git_index* index = lock.GetIndex();
// ... perform git operations ...
// Lock automatically released when object goes out of scope
int index
HISTORY_LOCK_MANAGER(const wxString &aProjectPath, int aStaleTimeoutSec=0)
Construct a lock manager and attempt to acquire locks.

Definition at line 58 of file history_lock.h.

Constructor & Destructor Documentation

◆ HISTORY_LOCK_MANAGER() [1/3]

HISTORY_LOCK_MANAGER::HISTORY_LOCK_MANAGER ( const wxString & aProjectPath,
int aStaleTimeoutSec = 0 )

Construct a lock manager and attempt to acquire locks.

Parameters
aProjectPathPath to the KiCad project directory
aStaleTimeoutSecTimeout in seconds after which a lock is considered stale and can be forcibly removed. If <= 0, uses the value from ADVANCED_CFG::m_HistoryLockStaleTimeout (default: 0 = use config)

Definition at line 49 of file history_lock.cpp.

References HISTORY_LOCK_MANAGER(), and historyPath().

Referenced by HISTORY_LOCK_MANAGER(), HISTORY_LOCK_MANAGER(), and operator=().

◆ HISTORY_LOCK_MANAGER() [2/3]

HISTORY_LOCK_MANAGER::HISTORY_LOCK_MANAGER ( const wxString & aProjectPath,
const wxString & aHistoryPath,
int aStaleTimeoutSec = 0 )

As above, with the history directory already resolved.

Background work must use this, since resolving reads the settings manager's project list, which the UI thread changes on load

Definition at line 55 of file history_lock.cpp.

References acquireFileLock(), acquireIndexLock(), HISTORY_LOCK_TRACE, m_historyPath, m_index, m_indexOwned, m_lockError, m_projectPath, m_repo, m_repoOwned, m_staleTimeoutSec, and openRepository().

◆ ~HISTORY_LOCK_MANAGER()

HISTORY_LOCK_MANAGER::~HISTORY_LOCK_MANAGER ( )

Destructor releases all locks and closes git repository.

Definition at line 93 of file history_lock.cpp.

References HISTORY_LOCK_TRACE, m_index, m_indexOwned, m_projectPath, m_repo, and m_repoOwned.

◆ HISTORY_LOCK_MANAGER() [3/3]

HISTORY_LOCK_MANAGER::HISTORY_LOCK_MANAGER ( const HISTORY_LOCK_MANAGER & )
delete

Member Function Documentation

◆ acquireFileLock()

bool HISTORY_LOCK_MANAGER::acquireFileLock ( )
private

◆ acquireIndexLock()

bool HISTORY_LOCK_MANAGER::acquireIndexLock ( )
private

Definition at line 226 of file history_lock.cpp.

References _, m_index, m_indexOwned, m_lockError, and m_repo.

Referenced by HISTORY_LOCK_MANAGER(), and ReopenRepository().

◆ BreakStaleLock()

bool HISTORY_LOCK_MANAGER::BreakStaleLock ( const wxString & aProjectPath)
static

Claim and remove an abandoned lock belonging to this user.

A lock held by another process or user is never removed.

Parameters
aProjectPathPath to project directory
Returns
true if lock was removed successfully

Definition at line 277 of file history_lock.cpp.

References historyLockPath(), and LOCKFILE::Locked().

◆ GetIndex()

git_index * HISTORY_LOCK_MANAGER::GetIndex ( )
inline

Get the git index handle (only valid if IsLocked() returns true).

Returns
Pointer to git_index, or nullptr if not locked

Definition at line 105 of file history_lock.h.

References m_index.

Referenced by LOCAL_HISTORY::commitInBackground(), commitSnapshotForProject(), and LOCAL_HISTORY::RestoreCommit().

◆ GetLockError()

wxString HISTORY_LOCK_MANAGER::GetLockError ( ) const

Get error message describing why lock could not be acquired.

Returns
Human-readable error message with details about lock holder

Definition at line 120 of file history_lock.cpp.

References m_lockError.

Referenced by LOCAL_HISTORY::commitInBackground(), and commitSnapshotForProject().

◆ GetLockHolder()

wxString HISTORY_LOCK_MANAGER::GetLockHolder ( ) const

Get information about who currently holds the lock.

Returns
String in format "username@hostname" or empty if lock is held by current process

Definition at line 126 of file history_lock.cpp.

References m_fileLock.

◆ GetRepository()

git_repository * HISTORY_LOCK_MANAGER::GetRepository ( )
inline

Get the git repository handle (only valid if IsLocked() returns true).

Returns
Pointer to git_repository, or nullptr if not locked

Definition at line 98 of file history_lock.h.

References m_repo.

Referenced by LOCAL_HISTORY::CommitDuplicateOfLastSave(), LOCAL_HISTORY::commitInBackground(), commitSnapshotForProject(), LOCAL_HISTORY::enforceSizeLimit(), LOCAL_HISTORY::RestoreCommit(), LOCAL_HISTORY::scheduleCompaction(), and LOCAL_HISTORY::TagSave().

◆ IsLocked()

bool HISTORY_LOCK_MANAGER::IsLocked ( ) const

Check if locks were successfully acquired.

Returns
true if both file lock and git repository are accessible

Definition at line 114 of file history_lock.cpp.

References m_fileLock, m_index, and m_repo.

Referenced by LOCAL_HISTORY::CommitDuplicateOfLastSave(), LOCAL_HISTORY::commitInBackground(), commitSnapshotForProject(), LOCAL_HISTORY::enforceSizeLimit(), operator=(), LOCAL_HISTORY::RestoreCommit(), LOCAL_HISTORY::scheduleCompaction(), and LOCAL_HISTORY::TagSave().

◆ IsLockStale()

bool HISTORY_LOCK_MANAGER::IsLockStale ( const wxString & aProjectPath,
int aStaleTimeoutSec = 0 )
static

Check if a lock file exists and is stale (older than timeout).

This does not acquire the lock, just checks its status.

Parameters
aProjectPathPath to project directory
aStaleTimeoutSecTimeout in seconds. If <= 0, uses the value from ADVANCED_CFG::m_HistoryLockStaleTimeout (default: 0 = use config)
Returns
true if lock exists and is stale

Definition at line 251 of file history_lock.cpp.

References ADVANCED_CFG::GetCfg(), HISTORY_LOCK_TRACE, historyLockPath(), LOCKFILE::Inspect(), LOCKFILE::LockPathFor(), ADVANCED_CFG::m_HistoryLockStaleTimeout, and LOCKFILE::Valid().

◆ openRepository()

bool HISTORY_LOCK_MANAGER::openRepository ( )
private

Definition at line 176 of file history_lock.cpp.

References _, m_historyPath, m_lockError, m_projectPath, m_repo, and m_repoOwned.

Referenced by HISTORY_LOCK_MANAGER(), and ReopenRepository().

◆ operator=()

HISTORY_LOCK_MANAGER & HISTORY_LOCK_MANAGER::operator= ( const HISTORY_LOCK_MANAGER & )
delete

◆ ReleaseRepository()

void HISTORY_LOCK_MANAGER::ReleaseRepository ( )

Release git repository and index handles early, but keep the file lock.

Definition at line 285 of file history_lock.cpp.

References m_index, m_indexOwned, m_repo, and m_repoOwned.

Referenced by LOCAL_HISTORY::enforceSizeLimit(), ReopenRepository(), and LOCAL_HISTORY::scheduleCompaction().

◆ ReopenRepository()

git_repository * HISTORY_LOCK_MANAGER::ReopenRepository ( )

Re-open the git repository and index after ReleaseRepository().

Exists so a caller can close the handle to work on the repository's files directly and then carry on; the file lock is held across the release, so no other process can have touched it in between.

Returns
the repository, or nullptr if the handles could not be re-acquired

Definition at line 303 of file history_lock.cpp.

References _, acquireIndexLock(), m_fileLock, m_index, m_lockError, m_repo, openRepository(), and ReleaseRepository().

Referenced by LOCAL_HISTORY::enforceSizeLimit().

Member Data Documentation

◆ m_fileLock

std::unique_ptr<LOCKFILE> HISTORY_LOCK_MANAGER::m_fileLock
private

Definition at line 158 of file history_lock.h.

Referenced by acquireFileLock(), GetLockHolder(), IsLocked(), and ReopenRepository().

◆ m_historyPath

wxString HISTORY_LOCK_MANAGER::m_historyPath
private

Definition at line 157 of file history_lock.h.

Referenced by acquireFileLock(), HISTORY_LOCK_MANAGER(), and openRepository().

◆ m_index

git_index* HISTORY_LOCK_MANAGER::m_index
private

◆ m_indexOwned

bool HISTORY_LOCK_MANAGER::m_indexOwned
private

◆ m_lockError

wxString HISTORY_LOCK_MANAGER::m_lockError
private

◆ m_projectPath

wxString HISTORY_LOCK_MANAGER::m_projectPath
private

Definition at line 156 of file history_lock.h.

Referenced by HISTORY_LOCK_MANAGER(), openRepository(), and ~HISTORY_LOCK_MANAGER().

◆ m_repo

git_repository* HISTORY_LOCK_MANAGER::m_repo
private

◆ m_repoOwned

bool HISTORY_LOCK_MANAGER::m_repoOwned
private

◆ m_staleTimeoutSec

int HISTORY_LOCK_MANAGER::m_staleTimeoutSec
private

Definition at line 164 of file history_lock.h.

Referenced by HISTORY_LOCK_MANAGER().


The documentation for this class was generated from the following files: