Fix crash by using a shared_mutex to read/write lock the nickIndex
Fixes sentry kicad-ax
This commit is contained in:
parent
62337f75b8
commit
5d793193e0
|
@ -193,6 +193,8 @@ LIB_TABLE_ROW* LIB_TABLE::findRow( const wxString& aNickName, bool aCheckIfEnabl
|
||||||
{
|
{
|
||||||
cur->ensureIndex();
|
cur->ensureIndex();
|
||||||
|
|
||||||
|
std::shared_lock<std::shared_mutex> lock( cur->m_nickIndexMutex );
|
||||||
|
|
||||||
for( const std::pair<const wxString, int>& entry : cur->m_nickIndex )
|
for( const std::pair<const wxString, int>& entry : cur->m_nickIndex )
|
||||||
{
|
{
|
||||||
if( entry.first == aNickName )
|
if( entry.first == aNickName )
|
||||||
|
@ -303,7 +305,7 @@ bool LIB_TABLE::InsertRow( LIB_TABLE_ROW* aRow, bool doReplace )
|
||||||
{
|
{
|
||||||
ensureIndex();
|
ensureIndex();
|
||||||
|
|
||||||
std::lock_guard<std::mutex> lock( m_nickIndexMutex );
|
std::lock_guard<std::shared_mutex> lock( m_nickIndexMutex );
|
||||||
|
|
||||||
INDEX_CITER it = m_nickIndex.find( aRow->GetNickName() );
|
INDEX_CITER it = m_nickIndex.find( aRow->GetNickName() );
|
||||||
|
|
||||||
|
|
|
@ -891,7 +891,7 @@ bool PANEL_SYM_LIB_TABLE::TransferDataFromWindow()
|
||||||
m_globalTable->Clear();
|
m_globalTable->Clear();
|
||||||
m_globalTable->m_rows.transfer( m_globalTable->m_rows.end(), global_model()->m_rows.begin(),
|
m_globalTable->m_rows.transfer( m_globalTable->m_rows.end(), global_model()->m_rows.begin(),
|
||||||
global_model()->m_rows.end(), global_model()->m_rows );
|
global_model()->m_rows.end(), global_model()->m_rows );
|
||||||
m_globalTable->reindex();
|
m_globalTable->reindex( true );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( project_model() && *project_model() != *m_projectTable )
|
if( project_model() && *project_model() != *m_projectTable )
|
||||||
|
@ -901,7 +901,7 @@ bool PANEL_SYM_LIB_TABLE::TransferDataFromWindow()
|
||||||
m_projectTable->Clear();
|
m_projectTable->Clear();
|
||||||
m_projectTable->m_rows.transfer( m_projectTable->m_rows.end(), project_model()->m_rows.begin(),
|
m_projectTable->m_rows.transfer( m_projectTable->m_rows.end(), project_model()->m_rows.begin(),
|
||||||
project_model()->m_rows.end(), project_model()->m_rows );
|
project_model()->m_rows.end(), project_model()->m_rows );
|
||||||
m_projectTable->reindex();
|
m_projectTable->reindex( true );
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include <boost/ptr_container/ptr_vector.hpp>
|
#include <boost/ptr_container/ptr_vector.hpp>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
#include <shared_mutex>
|
||||||
#include <project.h>
|
#include <project.h>
|
||||||
#include <string_utf8_map.h>
|
#include <string_utf8_map.h>
|
||||||
#include <richio.h>
|
#include <richio.h>
|
||||||
|
@ -329,7 +330,7 @@ public:
|
||||||
/// Delete all rows.
|
/// Delete all rows.
|
||||||
void Clear()
|
void Clear()
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock( m_nickIndexMutex );
|
std::lock_guard<std::shared_mutex> lock( m_nickIndexMutex );
|
||||||
|
|
||||||
m_rows.clear();
|
m_rows.clear();
|
||||||
m_nickIndex.clear();
|
m_nickIndex.clear();
|
||||||
|
@ -454,7 +455,7 @@ public:
|
||||||
if( *iter == *aRow )
|
if( *iter == *aRow )
|
||||||
{
|
{
|
||||||
m_rows.erase( iter, iter + 1 );
|
m_rows.erase( iter, iter + 1 );
|
||||||
reindex();
|
reindex( true );
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -539,9 +540,21 @@ protected:
|
||||||
*/
|
*/
|
||||||
bool migrate();
|
bool migrate();
|
||||||
|
|
||||||
void reindex()
|
/**
|
||||||
|
* Rebuilds the m_nickIndex
|
||||||
|
*
|
||||||
|
* @param aForce is to avoid rebuilding the index multiple times because multiple threads hit ensureIndex
|
||||||
|
* at the same time
|
||||||
|
*/
|
||||||
|
void reindex( bool aForce )
|
||||||
{
|
{
|
||||||
std::lock_guard<std::mutex> lock( m_nickIndexMutex );
|
std::lock_guard<std::shared_mutex> lock( m_nickIndexMutex );
|
||||||
|
|
||||||
|
if( !aForce )
|
||||||
|
{
|
||||||
|
if( m_nickIndex.size() )
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
m_nickIndex.clear();
|
m_nickIndex.clear();
|
||||||
|
|
||||||
|
@ -555,7 +568,7 @@ protected:
|
||||||
// Lazy indexing may be required. To handle lazy indexing, we must enforce
|
// Lazy indexing may be required. To handle lazy indexing, we must enforce
|
||||||
// that "nickIndex" is either empty or accurate, but never inaccurate.
|
// that "nickIndex" is either empty or accurate, but never inaccurate.
|
||||||
if( !m_nickIndex.size() )
|
if( !m_nickIndex.size() )
|
||||||
reindex();
|
reindex( false );
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -580,7 +593,7 @@ protected:
|
||||||
mutable int m_version;
|
mutable int m_version;
|
||||||
|
|
||||||
/// Mutex to protect access to the nickIndex variable
|
/// Mutex to protect access to the nickIndex variable
|
||||||
mutable std::mutex m_nickIndexMutex;
|
mutable std::shared_mutex m_nickIndexMutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // _LIB_TABLE_BASE_H_
|
#endif // _LIB_TABLE_BASE_H_
|
||||||
|
|
|
@ -989,7 +989,7 @@ bool PANEL_FP_LIB_TABLE::TransferDataFromWindow()
|
||||||
m_global->Clear();
|
m_global->Clear();
|
||||||
m_global->m_rows.transfer( m_global->m_rows.end(), global_model()->m_rows.begin(),
|
m_global->m_rows.transfer( m_global->m_rows.end(), global_model()->m_rows.begin(),
|
||||||
global_model()->m_rows.end(), global_model()->m_rows );
|
global_model()->m_rows.end(), global_model()->m_rows );
|
||||||
m_global->reindex();
|
m_global->reindex( true );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( project_model() && *project_model() != *m_project )
|
if( project_model() && *project_model() != *m_project )
|
||||||
|
@ -999,7 +999,7 @@ bool PANEL_FP_LIB_TABLE::TransferDataFromWindow()
|
||||||
m_project->Clear();
|
m_project->Clear();
|
||||||
m_project->m_rows.transfer( m_project->m_rows.end(), project_model()->m_rows.begin(),
|
m_project->m_rows.transfer( m_project->m_rows.end(), project_model()->m_rows.begin(),
|
||||||
project_model()->m_rows.end(), project_model()->m_rows );
|
project_model()->m_rows.end(), project_model()->m_rows );
|
||||||
m_project->reindex();
|
m_project->reindex( true );
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
Loading…
Reference in New Issue