diff --git a/common/design_block_info.cpp b/common/design_block_info.cpp index e915e73a29..55aedb95ec 100644 --- a/common/design_block_info.cpp +++ b/common/design_block_info.cpp @@ -96,16 +96,6 @@ bool DESIGN_BLOCK_INFO::InLibrary( const wxString& aLibrary ) const } -void DESIGN_BLOCK_INFO::ensure_loaded() -{ - // Lazy-loading. MUST NOT be called from multi-threaded environment. - LOCALE_IO toggle_locale; - - if( !m_loaded ) - load(); -} - - bool operator<( const DESIGN_BLOCK_INFO& lhs, const DESIGN_BLOCK_INFO& rhs ) { int retv = StrNumCmp( lhs.m_nickname, rhs.m_nickname, false ); diff --git a/common/design_block_info.h b/common/design_block_info.h index e14bb0f757..4816438681 100644 --- a/common/design_block_info.h +++ b/common/design_block_info.h @@ -42,6 +42,7 @@ class DESIGN_BLOCK_LIST_IMPL; class PROGRESS_REPORTER; class wxTopLevelWindow; class KIWAY; +class LOCALE_IO; class wxTextFile; @@ -106,10 +107,14 @@ public: friend bool operator<( const DESIGN_BLOCK_INFO& lhs, const DESIGN_BLOCK_INFO& rhs ); protected: - void ensure_loaded(); + void ensure_loaded() + { + if( !m_loaded ) + load(); + } /// lazily load stuff not filled in by constructor. This may throw IO_ERRORS. - virtual void load(){}; + virtual void load( const LOCALE_IO* locale = nullptr ) {}; protected: DESIGN_BLOCK_LIST* m_owner; ///< provides access to DESIGN_BLOCK_LIB_TABLE diff --git a/common/design_block_info_impl.cpp b/common/design_block_info_impl.cpp index fd80f64886..4fcaa1cfc1 100644 --- a/common/design_block_info_impl.cpp +++ b/common/design_block_info_impl.cpp @@ -35,14 +35,14 @@ #include -void DESIGN_BLOCK_INFO_IMPL::load() +void DESIGN_BLOCK_INFO_IMPL::load( const LOCALE_IO* locale ) { DESIGN_BLOCK_LIB_TABLE* dbtable = m_owner->GetTable(); wxASSERT( dbtable ); std::unique_ptr design_block( dbtable->GetEnumeratedDesignBlock( m_nickname, m_dbname, - true ) ); + locale ) ); if( design_block ) { @@ -164,7 +164,7 @@ void DESIGN_BLOCK_LIST_IMPL::loadDesignBlocks() std::vector> returns( num_elements ); auto db_thread = - [ this, &queue_parsed ]() -> size_t + [ this, &queue_parsed, &toggle_locale ]() -> size_t { wxString nickname; @@ -176,7 +176,7 @@ void DESIGN_BLOCK_LIST_IMPL::loadDesignBlocks() CatchErrors( [&]() { - m_lib_table->DesignBlockEnumerate( dbnames, nickname, false, true ); + m_lib_table->DesignBlockEnumerate( dbnames, nickname, false, &toggle_locale ); } ); for( wxString dbname : dbnames ) @@ -184,7 +184,7 @@ void DESIGN_BLOCK_LIST_IMPL::loadDesignBlocks() CatchErrors( [&]() { - auto* dbinfo = new DESIGN_BLOCK_INFO_IMPL( this, nickname, dbname ); + auto* dbinfo = new DESIGN_BLOCK_INFO_IMPL( this, nickname, dbname, &toggle_locale ); queue_parsed.move_push( std::unique_ptr( dbinfo ) ); } ); diff --git a/common/design_block_info_impl.h b/common/design_block_info_impl.h index 5491728eef..cdc2b55b5b 100644 --- a/common/design_block_info_impl.h +++ b/common/design_block_info_impl.h @@ -36,7 +36,7 @@ class KICOMMON_API DESIGN_BLOCK_INFO_IMPL : public DESIGN_BLOCK_INFO { public: DESIGN_BLOCK_INFO_IMPL( DESIGN_BLOCK_LIST* aOwner, const wxString& aNickname, - const wxString& aDesignBlockName ) + const wxString& aDesignBlockName, const LOCALE_IO* aLocale ) { m_nickname = aNickname; m_dbname = aDesignBlockName; @@ -44,7 +44,7 @@ public: m_owner = aOwner; m_loaded = false; - load(); + load( aLocale ); } // A constructor for cached items @@ -73,7 +73,7 @@ public: } protected: - virtual void load() override; + virtual void load( const LOCALE_IO* aLocale = nullptr ) override; }; diff --git a/common/design_block_lib_table.cpp b/common/design_block_lib_table.cpp index f89c2c9780..a1d07351c7 100644 --- a/common/design_block_lib_table.cpp +++ b/common/design_block_lib_table.cpp @@ -334,12 +334,12 @@ long long DESIGN_BLOCK_LIB_TABLE::GenerateTimestamp( const wxString* aNickname ) void DESIGN_BLOCK_LIB_TABLE::DesignBlockEnumerate( wxArrayString& aDesignBlockNames, const wxString& aNickname, - bool aBestEfforts, bool aThreadSafe ) + bool aBestEfforts, const LOCALE_IO* aLocale ) { const DESIGN_BLOCK_LIB_TABLE_ROW* row = FindRow( aNickname, true ); wxASSERT( row->plugin ); - if( !aThreadSafe ) + if( !aLocale ) { LOCALE_IO toggle_locale; @@ -402,12 +402,12 @@ static void setLibNickname( DESIGN_BLOCK* aModule, const wxString& aNickname, const DESIGN_BLOCK* DESIGN_BLOCK_LIB_TABLE::GetEnumeratedDesignBlock( const wxString& aNickname, const wxString& aDesignBlockName, - bool aThreadSafe ) + const LOCALE_IO* aLocale ) { const DESIGN_BLOCK_LIB_TABLE_ROW* row = FindRow( aNickname, true ); wxASSERT( row->plugin ); - if( !aThreadSafe ) + if( !aLocale ) { LOCALE_IO toggle_locale; diff --git a/common/design_block_tree_model_adapter.cpp b/common/design_block_tree_model_adapter.cpp index a7c7b23cfc..31c3a1f6e2 100644 --- a/common/design_block_tree_model_adapter.cpp +++ b/common/design_block_tree_model_adapter.cpp @@ -141,7 +141,7 @@ wxString DESIGN_BLOCK_TREE_MODEL_ADAPTER::GenerateInfo( LIB_ID const& aLibId, in try { - db = m_libs->GetEnumeratedDesignBlock( aLibId.GetLibNickname(), aLibId.GetLibItemName(), false ); + db = m_libs->GetEnumeratedDesignBlock( aLibId.GetLibNickname(), aLibId.GetLibItemName() ); } catch( const IO_ERROR& ioe ) { diff --git a/common/footprint_info.cpp b/common/footprint_info.cpp index d0abe43bdc..933c2e98ab 100644 --- a/common/footprint_info.cpp +++ b/common/footprint_info.cpp @@ -98,16 +98,6 @@ bool FOOTPRINT_INFO::InLibrary( const wxString& aLibrary ) const } -void FOOTPRINT_INFO::ensure_loaded() -{ - // Lazy-loading. MUST NOT be called from multi-threaded environment. - LOCALE_IO toggle_locale; - - if( !m_loaded ) - load(); -} - - bool operator<( const FOOTPRINT_INFO& lhs, const FOOTPRINT_INFO& rhs ) { int retv = StrNumCmp( lhs.m_nickname, rhs.m_nickname, false ); diff --git a/common/fp_lib_table.cpp b/common/fp_lib_table.cpp index befe56c4c1..84bab80cce 100644 --- a/common/fp_lib_table.cpp +++ b/common/fp_lib_table.cpp @@ -308,12 +308,12 @@ long long FP_LIB_TABLE::GenerateTimestamp( const wxString* aNickname ) void FP_LIB_TABLE::FootprintEnumerate( wxArrayString& aFootprintNames, const wxString& aNickname, - bool aBestEfforts, bool aThreadSafe ) + bool aBestEfforts, const LOCALE_IO* aLocale ) { const FP_LIB_TABLE_ROW* row = FindRow( aNickname, true ); wxASSERT( row->plugin ); - if( !aThreadSafe ) + if( !aLocale ) { LOCALE_IO toggle_locale; @@ -375,12 +375,12 @@ static void setLibNickname( FOOTPRINT* aModule, const wxString& aNickname, const FOOTPRINT* FP_LIB_TABLE::GetEnumeratedFootprint( const wxString& aNickname, const wxString& aFootprintName, - bool aThreadSafe ) + const LOCALE_IO* aLocale ) { const FP_LIB_TABLE_ROW* row = FindRow( aNickname, true ); wxASSERT( row->plugin ); - if( !aThreadSafe ) + if( !aLocale ) { LOCALE_IO toggle_locale; diff --git a/cvpcb/display_footprints_frame.cpp b/cvpcb/display_footprints_frame.cpp index 2c793448fc..5ee0a44436 100644 --- a/cvpcb/display_footprints_frame.cpp +++ b/cvpcb/display_footprints_frame.cpp @@ -304,7 +304,7 @@ FOOTPRINT* DISPLAY_FOOTPRINTS_FRAME::GetFootprint( const wxString& aFootprintNam try { - if( const FOOTPRINT* fp = fpTable->GetEnumeratedFootprint( libNickname, fpName, false ) ) + if( const FOOTPRINT* fp = fpTable->GetEnumeratedFootprint( libNickname, fpName ) ) footprint = static_cast( fp->Duplicate( IGNORE_PARENT_GROUP ) ); } catch( const IO_ERROR& ioe ) diff --git a/cvpcb/readwrite_dlgs.cpp b/cvpcb/readwrite_dlgs.cpp index 4689481eab..4a102eb5d0 100644 --- a/cvpcb/readwrite_dlgs.cpp +++ b/cvpcb/readwrite_dlgs.cpp @@ -58,7 +58,7 @@ static int guessNickname( FP_LIB_TABLE* aTbl, LIB_ID* aFootprintId ) { wxArrayString fpnames; - aTbl->FootprintEnumerate( fpnames, nicks[libNdx], true, false ); + aTbl->FootprintEnumerate( fpnames, nicks[libNdx], true ); for( unsigned nameNdx = 0; nameNdx < fpnames.size(); ++nameNdx ) { diff --git a/include/design_block_lib_table.h b/include/design_block_lib_table.h index b839f36c9f..d951d07d62 100644 --- a/include/design_block_lib_table.h +++ b/include/design_block_lib_table.h @@ -158,13 +158,13 @@ public: * \a aNickname. * @param aNickname is a locator for the "library", it is a "name" in LIB_TABLE_ROW. * @param aBestEfforts if true, don't throw on errors. - * @param aThreadSafe if true, do not set LOCALE_IO (which is global). Caller is responsible - * for setting it up correctly. + * @param aLocale a previously set-up locale. Currently required for multi-threading, as LOCALE_IO + * uses global storage. * * @throw IO_ERROR if the library cannot be found, or design block cannot be loaded. */ void DesignBlockEnumerate( wxArrayString& aDesignBlockNames, const wxString& aNickname, - bool aBestEfforts, bool aThreadSafe ); + bool aBestEfforts, const LOCALE_IO* aLocale = nullptr ); /** * Generate a hashed timestamp representing the last-mod-times of the library indicated @@ -197,13 +197,13 @@ public: * A version of #DesignBlockLoad() for use after #DesignBlockEnumerate() for more efficient * cache management. * - * @param aThreadSafe if true, do not set LOCALE_IO (which is global). Caller is responsible - * for setting it up correctly. + * @param aLocale a previously set-up locale. Currently required for multi-threading, as LOCALE_IO + * uses global storage. * * The return value is const to allow it to return a reference to a cached item. */ const DESIGN_BLOCK* GetEnumeratedDesignBlock( const wxString& aNickname, const wxString& aDesignBlockName, - bool aThreadSafe ); + const LOCALE_IO* aLocale = nullptr ); /** * The set of return values from DesignBlockSave() below. */ diff --git a/include/footprint_info.h b/include/footprint_info.h index 6ec1c8127d..e8e0f5f73f 100644 --- a/include/footprint_info.h +++ b/include/footprint_info.h @@ -46,6 +46,7 @@ class FOOTPRINT_LIST_IMPL; class PROGRESS_REPORTER; class wxTopLevelWindow; class KIWAY; +class LOCALE_IO; class wxTextFile; @@ -127,10 +128,14 @@ public: friend bool operator<( const FOOTPRINT_INFO& lhs, const FOOTPRINT_INFO& rhs ); protected: - void ensure_loaded(); + void ensure_loaded() + { + if( !m_loaded ) + load(); + } /// lazily load stuff not filled in by constructor. This may throw IO_ERRORS. - virtual void load() { }; + virtual void load( const LOCALE_IO* aLocale = nullptr ) { }; FOOTPRINT_LIST* m_owner; ///< provides access to FP_LIB_TABLE diff --git a/include/fp_lib_table.h b/include/fp_lib_table.h index de4b9a8824..7f8a49d34f 100644 --- a/include/fp_lib_table.h +++ b/include/fp_lib_table.h @@ -32,6 +32,7 @@ class FOOTPRINT; class FP_LIB_TABLE_GRID; class PCB_IO; +class LOCALE_IO; /** @@ -143,13 +144,13 @@ public: * @param aFootprintNames is the list to fill with the footprint names found in \a aNickname * @param aNickname is a locator for the "library", it is a "name" in LIB_TABLE_ROW. * @param aBestEfforts if true, don't throw on errors. - * @param aThreadSafe if true, do not set LOCALE_IO (which is global). Caller is responsible - * for setting it up correctly. + * @param aLocale a previously set-up locale. Currently required for multi-threading, as LOCALE_IO + * uses global storage. * * @throw IO_ERROR if the library cannot be found, or footprint cannot be loaded. */ void FootprintEnumerate( wxArrayString& aFootprintNames, const wxString& aNickname, - bool aBestEfforts, bool aThreadSafe ); + bool aBestEfforts, const LOCALE_IO* aLocale = nullptr ); /** * Generate a hashed timestamp representing the last-mod-times of the library indicated @@ -182,14 +183,14 @@ public: * A version of #FootprintLoad() for use after #FootprintEnumerate() for more efficient * cache management. * - * @param aThreadSafe if true, do not set LOCALE_IO (which is global). Caller is responsible - * for setting it up correctly. + * @param aLocale a previously set-up locale. Currently required for multi-threading, as LOCALE_IO + * uses global storage. * * The return value is const to allow it to return a reference to a cached item. */ const FOOTPRINT* GetEnumeratedFootprint( const wxString& aNickname, const wxString& aFootprintName, - bool aThreadSafe ); + const LOCALE_IO* aLocale = nullptr ); /** * The set of return values from FootprintSave() below. */ diff --git a/pcbnew/files.cpp b/pcbnew/files.cpp index 220882f678..5d9bf82432 100644 --- a/pcbnew/files.cpp +++ b/pcbnew/files.cpp @@ -75,7 +75,6 @@ #include #include #include // For ::ResolvePossibleSymlinks() -#include #include #include @@ -840,7 +839,6 @@ bool PCB_EDIT_FRAME::OpenProjectFiles( const std::vector& aFileSet, in // which prompts the user to continue with overwrite or abort) if( newLibPath.Length() > 0 ) { - LOCALE_IO toggle_locale; IO_RELEASER piSexpr( PCB_IO_MGR::PluginFind( PCB_IO_MGR::KICAD_SEXP ) ); for( FOOTPRINT* footprint : loadedFootprints ) diff --git a/pcbnew/footprint_info_impl.cpp b/pcbnew/footprint_info_impl.cpp index 6d45b09da7..2f585f36dd 100644 --- a/pcbnew/footprint_info_impl.cpp +++ b/pcbnew/footprint_info_impl.cpp @@ -41,13 +41,13 @@ #include -void FOOTPRINT_INFO_IMPL::load() +void FOOTPRINT_INFO_IMPL::load( const LOCALE_IO* aLocale ) { FP_LIB_TABLE* fptable = m_owner->GetTable(); wxASSERT( fptable ); - const FOOTPRINT* footprint = fptable->GetEnumeratedFootprint( m_nickname, m_fpname, true ); + const FOOTPRINT* footprint = fptable->GetEnumeratedFootprint( m_nickname, m_fpname, aLocale ); if( footprint == nullptr ) // Should happen only with malformed/broken libraries { @@ -180,7 +180,7 @@ void FOOTPRINT_LIST_IMPL::loadFootprints() std::vector> returns( num_elements ); auto fp_thread = - [ this, &queue_parsed ]() -> size_t + [ this, &queue_parsed, &toggle_locale ]() -> size_t { wxString nickname; @@ -192,7 +192,7 @@ void FOOTPRINT_LIST_IMPL::loadFootprints() CatchErrors( [&]() { - m_lib_table->FootprintEnumerate( fpnames, nickname, false, true ); + m_lib_table->FootprintEnumerate( fpnames, nickname, false, &toggle_locale ); } ); for( wxString fpname : fpnames ) @@ -200,7 +200,7 @@ void FOOTPRINT_LIST_IMPL::loadFootprints() CatchErrors( [&]() { - auto* fpinfo = new FOOTPRINT_INFO_IMPL( this, nickname, fpname ); + auto* fpinfo = new FOOTPRINT_INFO_IMPL( this, nickname, fpname, &toggle_locale ); queue_parsed.move_push( std::unique_ptr( fpinfo ) ); } ); diff --git a/pcbnew/footprint_info_impl.h b/pcbnew/footprint_info_impl.h index ed191271ff..fee0c569b6 100644 --- a/pcbnew/footprint_info_impl.h +++ b/pcbnew/footprint_info_impl.h @@ -34,8 +34,8 @@ class LOCALE_IO; class FOOTPRINT_INFO_IMPL : public FOOTPRINT_INFO { public: - FOOTPRINT_INFO_IMPL( FOOTPRINT_LIST* aOwner, const wxString& aNickname, - const wxString& aFootprintName ) + FOOTPRINT_INFO_IMPL( FOOTPRINT_LIST* aOwner, const wxString& aNickname, const wxString& aFootprintName, + const LOCALE_IO* aLocale ) { m_nickname = aNickname; m_fpname = aFootprintName; @@ -45,7 +45,7 @@ public: m_owner = aOwner; m_loaded = false; - load(); + load( aLocale ); } // A constructor for cached items @@ -77,7 +77,7 @@ public: } protected: - virtual void load() override; + virtual void load( const LOCALE_IO* aLocale ) override; }; diff --git a/pcbnew/footprint_libraries_utils.cpp b/pcbnew/footprint_libraries_utils.cpp index 325863d9e7..30a750fb71 100644 --- a/pcbnew/footprint_libraries_utils.cpp +++ b/pcbnew/footprint_libraries_utils.cpp @@ -51,7 +51,6 @@ #include #include #include -#include #include #include #include @@ -692,7 +691,6 @@ void PCB_EDIT_FRAME::ExportFootprintsToLibrary( bool aStoreInNewLib, const wxStr libNickname = row->GetNickName(); } - LOCALE_IO toggle_locale; PCB_IO_MGR::PCB_FILE_T piType = PCB_IO_MGR::KICAD_SEXP; IO_RELEASER pi( PCB_IO_MGR::PluginFind( piType ) ); std::map options { { "skip_cache_validation", "1" } }; // Skip cache validation -- we just created it @@ -1267,7 +1265,7 @@ FOOTPRINT* PCB_BASE_FRAME::CreateNewFootprint( wxString aFootprintName, const wx // Try to infer the footprint attributes from an existing footprint in the library try { - tbl->FootprintEnumerate( fpnames, aLibName, true, false ); + tbl->FootprintEnumerate( fpnames, aLibName, true, nullptr ); if( !fpnames.empty() ) footprintAttrs = tbl->FootprintLoad( aLibName, fpnames.Last() )->GetAttributes(); diff --git a/pcbnew/footprint_preview_panel.cpp b/pcbnew/footprint_preview_panel.cpp index eb406e2376..0e58e337a1 100644 --- a/pcbnew/footprint_preview_panel.cpp +++ b/pcbnew/footprint_preview_panel.cpp @@ -177,8 +177,7 @@ bool FOOTPRINT_PREVIEW_PANEL::DisplayFootprint( const LIB_ID& aFPID ) try { - const FOOTPRINT* fp = fptbl->GetEnumeratedFootprint( aFPID.GetLibNickname(), aFPID.GetLibItemName(), - false ); + const FOOTPRINT* fp = fptbl->GetEnumeratedFootprint( aFPID.GetLibNickname(), aFPID.GetLibItemName() ); if( fp ) m_currentFootprint.reset( static_cast( fp->Duplicate( IGNORE_PARENT_GROUP ) ) ); diff --git a/pcbnew/generate_footprint_info.cpp b/pcbnew/generate_footprint_info.cpp index 73525e9a46..a4a892ff10 100644 --- a/pcbnew/generate_footprint_info.cpp +++ b/pcbnew/generate_footprint_info.cpp @@ -122,8 +122,7 @@ public: try { m_footprint = m_fp_lib_table->GetEnumeratedFootprint( m_lib_id.GetLibNickname(), - m_lib_id.GetLibItemName(), - false ); + m_lib_id.GetLibItemName() ); } catch( const IO_ERROR& ioe ) { diff --git a/pcbnew/python/scripting/pcbnew_scripting_helpers.cpp b/pcbnew/python/scripting/pcbnew_scripting_helpers.cpp index b6399bb0ea..9141a58db9 100644 --- a/pcbnew/python/scripting/pcbnew_scripting_helpers.cpp +++ b/pcbnew/python/scripting/pcbnew_scripting_helpers.cpp @@ -392,7 +392,7 @@ wxArrayString GetFootprints( const wxString& aNickName ) if( !tbl ) return footprintNames; - tbl->FootprintEnumerate( footprintNames, aNickName, true, false ); + tbl->FootprintEnumerate( footprintNames, aNickName, true ); return footprintNames; } diff --git a/qa/pcbnew_utils/board_file_utils.cpp b/qa/pcbnew_utils/board_file_utils.cpp index 81e6fe8562..ddc3922beb 100644 --- a/qa/pcbnew_utils/board_file_utils.cpp +++ b/qa/pcbnew_utils/board_file_utils.cpp @@ -27,7 +27,6 @@ #include #include #include -#include #include #include @@ -148,7 +147,6 @@ std::unique_ptr ReadFootprintFromFileOrStream( const std::string& aFi void DumpFootprintToFile( const FOOTPRINT& aFootprint, const std::string& aLibraryPath ) { - LOCALE_IO toggle_locale; PCB_IO_KICAD_SEXPR io; io.FootprintSave( aLibraryPath, &aFootprint, nullptr ); }