Details
-
Bug
-
Resolution: Fixed
-
P2: Important
-
6.7.0 Beta2
-
None
-
3
-
7862453ba (dev), 039b2e4e5 (dev), 3265e2467 (6.7), 21177c79b (6.7), c4b0d1bd6 (6.6), 3a6031a99 (tqtc/lts-6.5)
Description
The QTzTimeZoneCache::findEntry() function is always called with QTzTimeZoneCache::m_mutex held, from its only caller, QTzTimeZoneCache::fetchEntry().
However, findEntry() performs quite heavy parsing, reading e.g. /etc/localtime or a file in /usr/share/zoneinfo/. These files are larger than 2KiB file on my system.
Even though findEntry() doesn't touch m_cache during its operation (it can be made a static instead of a non-static member function and it still compiles), it thus prevents other threads from looking up (and even parsing) other entries in the cache.
A very coarse solution would be to drop the mutex in fetchEntry() for the duration of the findEntry() call and then re-acquire it for the final m_cache.insert(). This means that more than one thread could parse the same file, and then one of the thread's result would be discarded. Having the file already in the OS cache would make this probably less of an issue than it sounds, but if it is, a more elaborate protocol could be implemented whereby the first thread registers its intent to parse a particular timezone file by allocating a dummy value in the cache, and the second thread, on finding the dummy value, would go to sleep on a wait-condition, to be woken once the first thread has finished.