From d1672af670a5e2a21589631fba223aa34ce57ee3 Mon Sep 17 00:00:00 2001 From: Konstantin Isakov Date: Thu, 3 Mar 2011 22:24:13 -0800 Subject: [PATCH] Fix Hunspell crashes when using multiple Hunspell dictionaries simultaneously. Evidently Hunspell is not reentrant, so we serialize all Hunspell calls using a single mutex. --- hunspell.cc | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/hunspell.cc b/hunspell.cc index 564121d3..032c5dbf 100644 --- a/hunspell.cc +++ b/hunspell.cc @@ -29,7 +29,6 @@ namespace { class HunspellDictionary: public Dictionary::Class { string name; - Mutex hunspellMutex; Hunspell hunspell; public: @@ -69,6 +68,20 @@ public: vector< wstring > const & alts, wstring const & ) throw( std::exception ); + +private: + + // We used to have a separate mutex for each Hunspell instance, assuming + // that its code was reentrant (though probably not thread-safe). However, + // crashes were discovered later when using several Hunspell dictionaries + // simultaneously, and we've switched to have a single mutex for all hunspell + // calls - evidently it's not really reentrant. + static Mutex & getHunspellMutex() + { + static Mutex mutex; + return mutex; + } +// Mutex hunspellMutex; }; /// Encodes the given string to be passed to the hunspell object. May throw @@ -259,7 +272,7 @@ sptr< DataRequest > HunspellDictionary::getArticle( wstring const & word, wstring const & ) throw( std::exception ) { - return new HunspellArticleRequest( word, hunspellMutex, hunspell ); + return new HunspellArticleRequest( word, getHunspellMutex(), hunspell ); } /// HunspellDictionary::findHeadwordsForSynonym() @@ -478,7 +491,7 @@ QVector< wstring > HunspellHeadwordsRequest::suggest( wstring & word ) sptr< WordSearchRequest > HunspellDictionary::findHeadwordsForSynonym( wstring const & word ) throw( std::exception ) { - return new HunspellHeadwordsRequest( word, hunspellMutex, hunspell ); + return new HunspellHeadwordsRequest( word, getHunspellMutex(), hunspell ); } @@ -593,7 +606,7 @@ sptr< WordSearchRequest > HunspellDictionary::prefixMatch( wstring const & word, unsigned long /*maxResults*/ ) throw( std::exception ) { - return new HunspellPrefixMatchRequest( word, hunspellMutex, hunspell ); + return new HunspellPrefixMatchRequest( word, getHunspellMutex(), hunspell ); }