]> git.lyx.org Git - features.git/commitdiff
Make theWordList() thread safe.
authorGeorg Baum <baum@lyx.org>
Sun, 6 Jul 2014 16:12:57 +0000 (18:12 +0200)
committerGeorg Baum <baum@lyx.org>
Sun, 6 Jul 2014 16:12:57 +0000 (18:12 +0200)
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
status.21x

index 3a095afca230c3dba23bd0a93b9a3f14316f4671..16f3b92e86e49c08c3f6c079d350f24f439a52ce 100644 (file)
@@ -18,6 +18,8 @@
 #include "support/lassert.h"
 #include "support/weighted_btree.h"
 
+#include <QThreadStorage>
+
 #include <map>
 
 using namespace std;
@@ -26,26 +28,37 @@ namespace lyx {
 
 ///
 typedef map<string, WordList *> 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<GlobalWordList *> 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();
 }
 
 
index a05a9dbe6ab42ca9c18162cff6c8218c9babb20d..11f13d99696707fbb14c9f5ffc5ca78304aa9f71 100644 (file)
@@ -63,7 +63,8 @@ What's new
 
 * INTERNALS
 
+- Improve thread-safety
+
 
 * DOCUMENTATION AND LOCALIZATION