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
(cherry picked from commit 7fe83993cf
)
This commit is contained in:
parent
330c0f86de
commit
686048dcce
|
@ -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__
|
#ifdef __APPLE__
|
||||||
// wxMessageDialog gets the button spacing wrong on Mac so we have to use wxRichMessageDialog.
|
// wxMessageDialog gets the button spacing wrong on Mac so we have to use wxRichMessageDialog.
|
||||||
|
|
|
@ -230,6 +230,15 @@ bool EDA_DRAW_FRAME::LockFile( const wxString& aFileName )
|
||||||
|
|
||||||
m_file_checker = std::make_unique<LOCKFILE>( 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
|
// 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
|
// locked or it could mean that the file is read-only
|
||||||
return m_file_checker->Valid();
|
return m_file_checker->Valid();
|
||||||
|
|
|
@ -161,6 +161,8 @@ void PGM_BASE::Destroy()
|
||||||
// unlike a normal destructor, this is designed to be called more than once safely:
|
// unlike a normal destructor, this is designed to be called more than once safely:
|
||||||
delete m_locale;
|
delete m_locale;
|
||||||
m_locale = nullptr;
|
m_locale = nullptr;
|
||||||
|
|
||||||
|
m_pgm_checker.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -443,6 +445,8 @@ bool PGM_BASE::InitPgm( bool aHeadless, bool aSkipPyInit, bool aIsUnitTest )
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
m_pgm_checker = std::make_unique<wxSingleInstanceChecker>();
|
||||||
|
m_pgm_checker->Create( pgm_name, wxStandardPaths::Get().GetTempDir() );
|
||||||
|
|
||||||
// Init KiCad environment
|
// Init KiCad environment
|
||||||
// the environment variable KICAD (if exists) gives the kicad path:
|
// the environment variable KICAD (if exists) gives the kicad path:
|
||||||
|
|
|
@ -103,7 +103,7 @@ bool SCH_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
|
||||||
{
|
{
|
||||||
msg.Printf( _( "Schematic '%s' is already open." ), wx_filename.GetFullName() );
|
msg.Printf( _( "Schematic '%s' is already open." ), wx_filename.GetFullName() );
|
||||||
|
|
||||||
if( !OverrideLock( this, msg ) )
|
if( !AskOverrideLock( this, msg ) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
m_file_checker->OverrideLock( false );
|
m_file_checker->OverrideLock( false );
|
||||||
|
|
|
@ -86,7 +86,7 @@ protected:
|
||||||
* Display a dialog indicating the file is already open, with an option to reset the lock.
|
* Display a dialog indicating the file is already open, with an option to reset the lock.
|
||||||
* @return true if the lock was reset.
|
* @return true if the lock was reset.
|
||||||
*/
|
*/
|
||||||
bool OverrideLock( wxWindow* aParent, const wxString& aMessage );
|
bool AskOverrideLock( wxWindow* aParent, const wxString& aMessage );
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -207,6 +207,11 @@ public:
|
||||||
return true;
|
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
|
* @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 <search_stack.h>
|
||||||
#include <settings/environment.h>
|
#include <settings/environment.h>
|
||||||
#include <wx/filename.h>
|
#include <wx/filename.h>
|
||||||
|
#include <wx/snglinst.h>
|
||||||
|
|
||||||
#undef pid_t
|
#undef pid_t
|
||||||
#include <pybind11/embed.h>
|
#include <pybind11/embed.h>
|
||||||
|
|
||||||
class wxSingleInstanceChecker;
|
|
||||||
class wxApp;
|
class wxApp;
|
||||||
class wxMenu;
|
class wxMenu;
|
||||||
class wxWindow;
|
class wxWindow;
|
||||||
|
@ -313,6 +313,14 @@ public:
|
||||||
*/
|
*/
|
||||||
bool IsGUI();
|
bool IsGUI();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
* wxWidgets on MSW tends to crash if you spool up more than one print job at a time.
|
||||||
*/
|
*/
|
||||||
|
@ -347,6 +355,10 @@ protected:
|
||||||
|
|
||||||
std::unique_ptr<SCRIPTING> m_python_scripting;
|
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_bin_dir; /// full path to this program
|
||||||
wxString m_kicad_env; /// The KICAD system environment variable.
|
wxString m_kicad_env; /// The KICAD system environment variable.
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,7 @@
|
||||||
#include <widgets/wx_progress_reporters.h>
|
#include <widgets/wx_progress_reporters.h>
|
||||||
#include <settings/settings_manager.h>
|
#include <settings/settings_manager.h>
|
||||||
#include <paths.h>
|
#include <paths.h>
|
||||||
|
#include <pgm_base.h>
|
||||||
#include <project/project_file.h>
|
#include <project/project_file.h>
|
||||||
#include <project/project_local_settings.h>
|
#include <project/project_local_settings.h>
|
||||||
#include <project/net_settings.h>
|
#include <project/net_settings.h>
|
||||||
|
@ -611,12 +612,23 @@ bool PCB_EDIT_FRAME::OpenProjectFiles( const std::vector<wxString>& aFileSet, in
|
||||||
|
|
||||||
std::unique_ptr<LOCKFILE> lock = std::make_unique<LOCKFILE>( fullFileName );
|
std::unique_ptr<LOCKFILE> lock = std::make_unique<LOCKFILE>( fullFileName );
|
||||||
|
|
||||||
if( !lock->Locked() )
|
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(),
|
msg.Printf( _( "PCB '%s' is already open by '%s' at '%s'." ), wx_filename.GetFullName(),
|
||||||
lock->GetUsername(), lock->GetHostname() );
|
lock->GetUsername(), lock->GetHostname() );
|
||||||
|
|
||||||
if( !OverrideLock( this, msg ) )
|
if( !AskOverrideLock( this, msg ) )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
lock->OverrideLock();
|
lock->OverrideLock();
|
||||||
|
|
Loading…
Reference in New Issue