From f5cf3705d50b2cde45369e4707f57ea95995fada Mon Sep 17 00:00:00 2001 From: Georg Baum Date: Sun, 6 Jul 2014 18:12:57 +0200 Subject: [PATCH] Make theWordList() thread safe. Without this, you get crashes in a few second when you set the autosave interval to one second and edit quickly (typing new words etc). The reason is that the cloned buffer wants to insert words into the word list and remove them again, but it lives in a different thread. --- src/WordList.cpp | 31 ++++++++++++++++++++++--------- status.21x | 3 ++- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/src/WordList.cpp b/src/WordList.cpp index 3a095afca2..16f3b92e86 100644 --- a/src/WordList.cpp +++ b/src/WordList.cpp @@ -18,6 +18,8 @@ #include "support/lassert.h" #include "support/weighted_btree.h" +#include + #include using namespace std; @@ -26,26 +28,37 @@ namespace lyx { /// typedef map GlobalWordList; -GlobalWordList theGlobalWordList; +// Each thread uses its own word list, but only the one of the GUI thread is +// used to do real work. The others are only neded to prevent simultanous +// write access e.g. from a cloned buffer and a true document buffer. +QThreadStorage theGlobalWordList; WordList * theWordList(string const & lang) { - GlobalWordList::iterator it = theGlobalWordList.find(lang); - if (it != theGlobalWordList.end()) + if (!theGlobalWordList.hasLocalData()) + theGlobalWordList.setLocalData(new GlobalWordList); + GlobalWordList * globalWordList = theGlobalWordList.localData(); + GlobalWordList::iterator it = globalWordList->find(lang); + if (it != globalWordList->end()) return it->second; - else - theGlobalWordList[lang] = new WordList; - return theGlobalWordList[lang]; + else { + WordList * wl = new WordList; + (*globalWordList)[lang] = wl; + return wl; + } } void WordList::cleanupWordLists() { - GlobalWordList::const_iterator it = theGlobalWordList.begin(); - for (; it != theGlobalWordList.end(); ++it) + if (!theGlobalWordList.hasLocalData()) + return; + GlobalWordList * globalWordList = theGlobalWordList.localData(); + GlobalWordList::const_iterator it = globalWordList->begin(); + for (; it != globalWordList->end(); ++it) delete it->second; - theGlobalWordList.clear(); + globalWordList->clear(); } diff --git a/status.21x b/status.21x index a05a9dbe6a..11f13d9969 100644 --- a/status.21x +++ b/status.21x @@ -63,7 +63,8 @@ What's new * INTERNALS - +- Improve thread-safety + * DOCUMENTATION AND LOCALIZATION -- 2.39.5