Be smarter about releasing lockfiles
If KiCad crashes or exits without deleting the lockfile, don't show the warning message unless we are not the one who locked it or there are other KiCad instances running locally. This should catch 99% of the cases where the message is shown incorrectly. There may be some corner cases where the lock file is created on a network drive using two different machines with the same name and same user but these cases should be (famous last words) sufficiently rare as to not be observed in practice
This commit is contained in:
parent
e71422d2cf
commit
7fe83993cf
|
@ -155,7 +155,7 @@ long KIDIALOG::getStyle( KD_TYPE aType )
|
|||
}
|
||||
|
||||
|
||||
bool OverrideLock( wxWindow* aParent, const wxString& aMessage )
|
||||
bool AskOverrideLock( wxWindow* aParent, const wxString& aMessage )
|
||||
{
|
||||
#ifdef __APPLE__
|
||||
// wxMessageDialog gets the button spacing wrong on Mac so we have to use wxRichMessageDialog.
|
||||
|
|
|
@ -226,6 +226,15 @@ bool EDA_DRAW_FRAME::LockFile( const wxString& aFileName )
|
|||
|
||||
m_file_checker = std::make_unique<LOCKFILE>( aFileName );
|
||||
|
||||
if( !m_file_checker->Valid() && m_file_checker->IsLockedByMe() )
|
||||
{
|
||||
// If we cannot acquire the lock but we appear to be the one who
|
||||
// locked it, check to see if there is another KiCad instance running.
|
||||
// If there is not, then we can override the lock. This could happen if
|
||||
// KiCad crashed or was interrupted
|
||||
if( !Pgm().SingleInstance()->IsAnotherRunning() )
|
||||
m_file_checker->OverrideLock();
|
||||
}
|
||||
// If the file is valid, return true. This could mean that the file is
|
||||
// locked or it could mean that the file is read-only
|
||||
return m_file_checker->Valid();
|
||||
|
|
|
@ -166,6 +166,8 @@ void PGM_BASE::Destroy()
|
|||
// unlike a normal destructor, this is designed to be called more than once safely:
|
||||
delete m_locale;
|
||||
m_locale = nullptr;
|
||||
|
||||
m_pgm_checker.reset();
|
||||
}
|
||||
|
||||
|
||||
|
@ -470,6 +472,8 @@ bool PGM_BASE::InitPgm( bool aHeadless, bool aSkipPyInit, bool aIsUnitTest )
|
|||
return false;
|
||||
}
|
||||
#endif
|
||||
m_pgm_checker = std::make_unique<wxSingleInstanceChecker>();
|
||||
m_pgm_checker->Create( pgm_name, wxStandardPaths::Get().GetTempDir() );
|
||||
|
||||
// Init KiCad environment
|
||||
// the environment variable KICAD (if exists) gives the kicad path:
|
||||
|
|
|
@ -108,7 +108,7 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
|
|||
msg.Printf( _( "Schematic '%s' is already open by '%s' at '%s'." ), fullFileName,
|
||||
m_file_checker->GetUsername(), m_file_checker->GetHostname() );
|
||||
|
||||
if( !OverrideLock( this, msg ) )
|
||||
if( !AskOverrideLock( this, msg ) )
|
||||
return false;
|
||||
|
||||
m_file_checker->OverrideLock();
|
||||
|
|
|
@ -86,7 +86,7 @@ protected:
|
|||
* Display a dialog indicating the file is already open, with an option to reset the lock.
|
||||
* @return true if the lock was reset.
|
||||
*/
|
||||
bool OverrideLock( wxWindow* aParent, const wxString& aMessage );
|
||||
bool AskOverrideLock( wxWindow* aParent, const wxString& aMessage );
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
@ -208,6 +208,11 @@ public:
|
|||
return true;
|
||||
}
|
||||
|
||||
bool IsLockedByMe()
|
||||
{
|
||||
return m_username == wxGetUserId() && m_hostname == wxGetHostName();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Current username. If we own the lock, this is us. Otherwise, this is the user that does own it
|
||||
*/
|
||||
|
|
|
@ -38,11 +38,11 @@
|
|||
#include <search_stack.h>
|
||||
#include <settings/environment.h>
|
||||
#include <wx/filename.h>
|
||||
#include <wx/snglinst.h>
|
||||
|
||||
#undef pid_t
|
||||
#include <pybind11/embed.h>
|
||||
|
||||
class wxSingleInstanceChecker;
|
||||
class wxApp;
|
||||
class wxMenu;
|
||||
class wxWindow;
|
||||
|
@ -357,6 +357,14 @@ public:
|
|||
void ShowSplash();
|
||||
void HideSplash();
|
||||
|
||||
/**
|
||||
* Allows access to the wxSingleInstanceChecker to test for other running KiCads
|
||||
*/
|
||||
std::unique_ptr<wxSingleInstanceChecker>& SingleInstance()
|
||||
{
|
||||
return m_pgm_checker;
|
||||
}
|
||||
|
||||
/**
|
||||
* wxWidgets on MSW tends to crash if you spool up more than one print job at a time.
|
||||
*/
|
||||
|
@ -391,6 +399,10 @@ protected:
|
|||
|
||||
std::unique_ptr<SCRIPTING> m_python_scripting;
|
||||
|
||||
/// Checks if there is another copy of Kicad running at the same time
|
||||
std::unique_ptr<wxSingleInstanceChecker> m_pgm_checker;
|
||||
|
||||
|
||||
wxString m_bin_dir; /// full path to this program
|
||||
wxString m_kicad_env; /// The KICAD system environment variable.
|
||||
|
||||
|
|
|
@ -49,6 +49,7 @@
|
|||
#include <widgets/wx_progress_reporters.h>
|
||||
#include <settings/settings_manager.h>
|
||||
#include <paths.h>
|
||||
#include <pgm_base.h>
|
||||
#include <project/project_file.h>
|
||||
#include <project/project_local_settings.h>
|
||||
#include <project/net_settings.h>
|
||||
|
@ -606,12 +607,23 @@ bool PCB_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
|
|||
|
||||
std::unique_ptr<LOCKFILE> lock = std::make_unique<LOCKFILE>( fullFileName );
|
||||
|
||||
if( !lock->Valid() && lock->IsLockedByMe() )
|
||||
{
|
||||
// If we cannot acquire the lock but we appear to be the one who
|
||||
// locked it, check to see if there is another KiCad instance running.
|
||||
// If there is not, then we can override the lock. This could happen if
|
||||
// KiCad crashed or was interrupted
|
||||
|
||||
if( !Pgm().SingleInstance()->IsAnotherRunning() )
|
||||
lock->OverrideLock();
|
||||
}
|
||||
|
||||
if( !lock->Valid() )
|
||||
{
|
||||
msg.Printf( _( "PCB '%s' is already open by '%s' at '%s'." ), wx_filename.GetFullName(),
|
||||
lock->GetUsername(), lock->GetHostname() );
|
||||
|
||||
if( !OverrideLock( this, msg ) )
|
||||
if( !AskOverrideLock( this, msg ) )
|
||||
return false;
|
||||
|
||||
lock->OverrideLock();
|
||||
|
|
Loading…
Reference in New Issue