diff --git a/eeschema/dialogs/panel_sym_lib_table.cpp b/eeschema/dialogs/panel_sym_lib_table.cpp index f4a8a627c0..0b187eecc5 100644 --- a/eeschema/dialogs/panel_sym_lib_table.cpp +++ b/eeschema/dialogs/panel_sym_lib_table.cpp @@ -891,7 +891,7 @@ bool PANEL_SYM_LIB_TABLE::TransferDataFromWindow() m_globalTable->Clear(); m_globalTable->m_rows.transfer( m_globalTable->m_rows.end(), global_model()->m_rows.begin(), global_model()->m_rows.end(), global_model()->m_rows ); - m_globalTable->reindex( true ); + m_globalTable->reindex(); } if( project_model() && *project_model() != *m_projectTable ) @@ -901,7 +901,7 @@ bool PANEL_SYM_LIB_TABLE::TransferDataFromWindow() m_projectTable->Clear(); m_projectTable->m_rows.transfer( m_projectTable->m_rows.end(), project_model()->m_rows.begin(), project_model()->m_rows.end(), project_model()->m_rows ); - m_projectTable->reindex( true ); + m_projectTable->reindex(); } return true; diff --git a/include/lib_table_base.h b/include/lib_table_base.h index 41304a4a75..e9a35bbb63 100644 --- a/include/lib_table_base.h +++ b/include/lib_table_base.h @@ -455,7 +455,7 @@ public: if( *iter == *aRow ) { m_rows.erase( iter, iter + 1 ); - reindex( true ); + reindex(); return true; } } @@ -521,6 +521,18 @@ public: return m_version; } + /** + * While this is an encapsulation leak, calling it before threaded loads *may* prevent + * some Sentry crashes we're seeing (KICAD-4S). + */ + void EnsureIndex() + { + ensureIndex(); + + if( m_fallBack ) + m_fallBack->EnsureIndex(); + } + protected: /** * Return a #LIB_TABLE_ROW if \a aNickname is found in this table or in any chained @@ -546,16 +558,10 @@ protected: * @param aForce is to avoid rebuilding the index multiple times because multiple threads hit ensureIndex * at the same time */ - void reindex( bool aForce ) + void reindex() { std::lock_guard lock( m_nickIndexMutex ); - if( !aForce ) - { - if( m_nickIndex.size() ) - return; - } - m_nickIndex.clear(); for( LIB_TABLE_ROWS_ITER it = m_rows.begin(); it != m_rows.end(); ++it ) @@ -567,8 +573,14 @@ protected: // The dialog lib table editor may not maintain the nickIndex. // Lazy indexing may be required. To handle lazy indexing, we must enforce // that "nickIndex" is either empty or accurate, but never inaccurate. - if( !m_nickIndex.size() ) - reindex( false ); + { + std::shared_lock lock( m_nickIndexMutex ); + + if( m_nickIndex.size() ) + return; + } + + reindex(); } private: diff --git a/pcbnew/dialogs/panel_fp_lib_table.cpp b/pcbnew/dialogs/panel_fp_lib_table.cpp index 2141d5acca..05d09c0d7d 100644 --- a/pcbnew/dialogs/panel_fp_lib_table.cpp +++ b/pcbnew/dialogs/panel_fp_lib_table.cpp @@ -989,7 +989,7 @@ bool PANEL_FP_LIB_TABLE::TransferDataFromWindow() m_global->Clear(); m_global->m_rows.transfer( m_global->m_rows.end(), global_model()->m_rows.begin(), global_model()->m_rows.end(), global_model()->m_rows ); - m_global->reindex( true ); + m_global->reindex(); } if( project_model() && *project_model() != *m_project ) @@ -999,7 +999,7 @@ bool PANEL_FP_LIB_TABLE::TransferDataFromWindow() m_project->Clear(); m_project->m_rows.transfer( m_project->m_rows.end(), project_model()->m_rows.begin(), project_model()->m_rows.end(), project_model()->m_rows ); - m_project->reindex( true ); + m_project->reindex(); } return true; diff --git a/pcbnew/footprint_info_impl.cpp b/pcbnew/footprint_info_impl.cpp index b1356ef419..ddabcd5ae5 100644 --- a/pcbnew/footprint_info_impl.cpp +++ b/pcbnew/footprint_info_impl.cpp @@ -266,6 +266,12 @@ void FOOTPRINT_LIST_IMPL::loadFootprints() return 1; }; + // While the private ensureIndex() is supposedly thread-safe, and having a public call is + // a bit of an encapsulation leak, we have at least one non-reproducible Sentry issue + // (KICAD-4S) that *might* be prevented by doing the EnsureIndex() before spooling up the + // multi-threaded part. + m_lib_table->EnsureIndex(); + for( size_t ii = 0; ii < num_elements; ++ii ) returns[ii] = tp.submit( fp_thread );