Made some more global functions thread-safe by using locks. Avoids a race condition in the multi-threaded initialization code.
This commit is contained in:
parent
a4f3abf6a0
commit
8724767980
107
src/Global.cpp
107
src/Global.cpp
@ -200,11 +200,16 @@ static const unsigned int g_lamexp_toolver_coreaudio = VER_LAMEXP_TOOL_COREAUDIO
|
|||||||
|
|
||||||
//Special folders
|
//Special folders
|
||||||
static QString g_lamexp_temp_folder;
|
static QString g_lamexp_temp_folder;
|
||||||
|
static QReadWriteLock g_lamexp_folder_lock;
|
||||||
|
|
||||||
//Tools
|
//Tools
|
||||||
static QMap<QString, LockedFile*> g_lamexp_tool_registry;
|
static struct
|
||||||
static QMap<QString, unsigned int> g_lamexp_tool_versions;
|
{
|
||||||
static QReadWriteLock g_lamexp_tool_lock;
|
QMap<QString, LockedFile*> registry;
|
||||||
|
QMap<QString, unsigned int> versions;
|
||||||
|
QReadWriteLock lock;
|
||||||
|
}
|
||||||
|
g_lamexp_tools;
|
||||||
|
|
||||||
//Languages
|
//Languages
|
||||||
static struct
|
static struct
|
||||||
@ -213,11 +218,18 @@ static struct
|
|||||||
QMap<QString, QString> names;
|
QMap<QString, QString> names;
|
||||||
QMap<QString, unsigned int> sysid;
|
QMap<QString, unsigned int> sysid;
|
||||||
QMap<QString, unsigned int> cntry;
|
QMap<QString, unsigned int> cntry;
|
||||||
|
QReadWriteLock lock;
|
||||||
}
|
}
|
||||||
g_lamexp_translation;
|
g_lamexp_translation;
|
||||||
|
|
||||||
//Translator
|
//Translator
|
||||||
static QTranslator *g_lamexp_currentTranslator = NULL;
|
static struct
|
||||||
|
{
|
||||||
|
QVariant instance;
|
||||||
|
QReadWriteLock lock;
|
||||||
|
|
||||||
|
}
|
||||||
|
g_lamexp_currentTranslator;
|
||||||
|
|
||||||
//Shared memory
|
//Shared memory
|
||||||
static const struct
|
static const struct
|
||||||
@ -1160,8 +1172,10 @@ bool lamexp_init_qt(int argc, char* argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Add default translations
|
//Add default translations
|
||||||
|
QWriteLocker writeLockTranslations(&g_lamexp_translation.lock);
|
||||||
g_lamexp_translation.files.insert(LAMEXP_DEFAULT_LANGID, "");
|
g_lamexp_translation.files.insert(LAMEXP_DEFAULT_LANGID, "");
|
||||||
g_lamexp_translation.names.insert(LAMEXP_DEFAULT_LANGID, "English");
|
g_lamexp_translation.names.insert(LAMEXP_DEFAULT_LANGID, "English");
|
||||||
|
writeLockTranslations.unlock();
|
||||||
|
|
||||||
//Check for process elevation
|
//Check for process elevation
|
||||||
if((!lamexp_check_elevation()) && (!lamexp_detect_wine()))
|
if((!lamexp_check_elevation()) && (!lamexp_detect_wine()))
|
||||||
@ -1390,9 +1404,7 @@ QString lamexp_rand_str(void)
|
|||||||
*/
|
*/
|
||||||
const QString &lamexp_temp_folder2(void)
|
const QString &lamexp_temp_folder2(void)
|
||||||
{
|
{
|
||||||
static const char *TEMP_STR = "Temp";
|
QReadLocker readLock(&g_lamexp_folder_lock);
|
||||||
const QString WRITE_TEST_DATA = lamexp_rand_str();
|
|
||||||
const QString SUB_FOLDER = lamexp_rand_str();
|
|
||||||
|
|
||||||
//Already initialized?
|
//Already initialized?
|
||||||
if(!g_lamexp_temp_folder.isEmpty())
|
if(!g_lamexp_temp_folder.isEmpty())
|
||||||
@ -1401,12 +1413,16 @@ const QString &lamexp_temp_folder2(void)
|
|||||||
{
|
{
|
||||||
return g_lamexp_temp_folder;
|
return g_lamexp_temp_folder;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
g_lamexp_temp_folder.clear();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
readLock.unlock();
|
||||||
|
QWriteLocker writeLock(&g_lamexp_folder_lock);
|
||||||
|
g_lamexp_temp_folder.clear();
|
||||||
|
|
||||||
|
static const char *TEMP_STR = "Temp";
|
||||||
|
const QString WRITE_TEST_DATA = lamexp_rand_str();
|
||||||
|
const QString SUB_FOLDER = lamexp_rand_str();
|
||||||
|
|
||||||
//Try the %TMP% or %TEMP% directory first
|
//Try the %TMP% or %TEMP% directory first
|
||||||
QDir temp = QDir::temp();
|
QDir temp = QDir::temp();
|
||||||
if(temp.exists())
|
if(temp.exists())
|
||||||
@ -1507,15 +1523,15 @@ bool lamexp_clean_folder(const QString &folderPath)
|
|||||||
*/
|
*/
|
||||||
void lamexp_register_tool(const QString &toolName, LockedFile *file, unsigned int version)
|
void lamexp_register_tool(const QString &toolName, LockedFile *file, unsigned int version)
|
||||||
{
|
{
|
||||||
QWriteLocker writeLock(&g_lamexp_tool_lock);
|
QWriteLocker writeLock(&g_lamexp_tools.lock);
|
||||||
|
|
||||||
if(g_lamexp_tool_registry.contains(toolName.toLower()))
|
if(g_lamexp_tools.registry.contains(toolName.toLower()))
|
||||||
{
|
{
|
||||||
throw "lamexp_register_tool: Tool is already registered!";
|
throw "lamexp_register_tool: Tool is already registered!";
|
||||||
}
|
}
|
||||||
|
|
||||||
g_lamexp_tool_registry.insert(toolName.toLower(), file);
|
g_lamexp_tools.registry.insert(toolName.toLower(), file);
|
||||||
g_lamexp_tool_versions.insert(toolName.toLower(), version);
|
g_lamexp_tools.versions.insert(toolName.toLower(), version);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1523,8 +1539,8 @@ void lamexp_register_tool(const QString &toolName, LockedFile *file, unsigned in
|
|||||||
*/
|
*/
|
||||||
bool lamexp_check_tool(const QString &toolName)
|
bool lamexp_check_tool(const QString &toolName)
|
||||||
{
|
{
|
||||||
QReadLocker readLock(&g_lamexp_tool_lock);
|
QReadLocker readLock(&g_lamexp_tools.lock);
|
||||||
return g_lamexp_tool_registry.contains(toolName.toLower());
|
return g_lamexp_tools.registry.contains(toolName.toLower());
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1532,11 +1548,11 @@ bool lamexp_check_tool(const QString &toolName)
|
|||||||
*/
|
*/
|
||||||
const QString lamexp_lookup_tool(const QString &toolName)
|
const QString lamexp_lookup_tool(const QString &toolName)
|
||||||
{
|
{
|
||||||
QReadLocker readLock(&g_lamexp_tool_lock);
|
QReadLocker readLock(&g_lamexp_tools.lock);
|
||||||
|
|
||||||
if(g_lamexp_tool_registry.contains(toolName.toLower()))
|
if(g_lamexp_tools.registry.contains(toolName.toLower()))
|
||||||
{
|
{
|
||||||
return g_lamexp_tool_registry.value(toolName.toLower())->filePath();
|
return g_lamexp_tools.registry.value(toolName.toLower())->filePath();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1549,11 +1565,11 @@ const QString lamexp_lookup_tool(const QString &toolName)
|
|||||||
*/
|
*/
|
||||||
unsigned int lamexp_tool_version(const QString &toolName)
|
unsigned int lamexp_tool_version(const QString &toolName)
|
||||||
{
|
{
|
||||||
QReadLocker readLock(&g_lamexp_tool_lock);
|
QReadLocker readLock(&g_lamexp_tools.lock);
|
||||||
|
|
||||||
if(g_lamexp_tool_versions.contains(toolName.toLower()))
|
if(g_lamexp_tools.versions.contains(toolName.toLower()))
|
||||||
{
|
{
|
||||||
return g_lamexp_tool_versions.value(toolName.toLower());
|
return g_lamexp_tools.versions.value(toolName.toLower());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -1597,6 +1613,8 @@ const QString lamexp_version2string(const QString &pattern, unsigned int version
|
|||||||
*/
|
*/
|
||||||
bool lamexp_translation_register(const QString &langId, const QString &qmFile, const QString &langName, unsigned int &systemId, unsigned int &country)
|
bool lamexp_translation_register(const QString &langId, const QString &qmFile, const QString &langName, unsigned int &systemId, unsigned int &country)
|
||||||
{
|
{
|
||||||
|
QWriteLocker writeLockTranslations(&g_lamexp_translation.lock);
|
||||||
|
|
||||||
if(qmFile.isEmpty() || langName.isEmpty() || systemId < 1)
|
if(qmFile.isEmpty() || langName.isEmpty() || systemId < 1)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
@ -1615,6 +1633,7 @@ bool lamexp_translation_register(const QString &langId, const QString &qmFile, c
|
|||||||
*/
|
*/
|
||||||
QStringList lamexp_query_translations(void)
|
QStringList lamexp_query_translations(void)
|
||||||
{
|
{
|
||||||
|
QReadLocker writeLockTranslations(&g_lamexp_translation.lock);
|
||||||
return g_lamexp_translation.files.keys();
|
return g_lamexp_translation.files.keys();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1623,6 +1642,7 @@ QStringList lamexp_query_translations(void)
|
|||||||
*/
|
*/
|
||||||
QString lamexp_translation_name(const QString &langId)
|
QString lamexp_translation_name(const QString &langId)
|
||||||
{
|
{
|
||||||
|
QReadLocker writeLockTranslations(&g_lamexp_translation.lock);
|
||||||
return g_lamexp_translation.names.value(langId.toLower(), QString());
|
return g_lamexp_translation.names.value(langId.toLower(), QString());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1631,6 +1651,7 @@ QString lamexp_translation_name(const QString &langId)
|
|||||||
*/
|
*/
|
||||||
unsigned int lamexp_translation_sysid(const QString &langId)
|
unsigned int lamexp_translation_sysid(const QString &langId)
|
||||||
{
|
{
|
||||||
|
QReadLocker writeLockTranslations(&g_lamexp_translation.lock);
|
||||||
return g_lamexp_translation.sysid.value(langId.toLower(), 0);
|
return g_lamexp_translation.sysid.value(langId.toLower(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1639,6 +1660,7 @@ unsigned int lamexp_translation_sysid(const QString &langId)
|
|||||||
*/
|
*/
|
||||||
unsigned int lamexp_translation_country(const QString &langId)
|
unsigned int lamexp_translation_country(const QString &langId)
|
||||||
{
|
{
|
||||||
|
QReadLocker writeLockTranslations(&g_lamexp_translation.lock);
|
||||||
return g_lamexp_translation.cntry.value(langId.toLower(), 0);
|
return g_lamexp_translation.cntry.value(langId.toLower(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1655,6 +1677,7 @@ bool lamexp_install_translator(const QString &langId)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
QReadLocker readLock(&g_lamexp_translation.lock);
|
||||||
QString qmFile = g_lamexp_translation.files.value(langId.toLower(), QString());
|
QString qmFile = g_lamexp_translation.files.value(langId.toLower(), QString());
|
||||||
if(!qmFile.isEmpty())
|
if(!qmFile.isEmpty())
|
||||||
{
|
{
|
||||||
@ -1674,27 +1697,31 @@ bool lamexp_install_translator(const QString &langId)
|
|||||||
*/
|
*/
|
||||||
bool lamexp_install_translator_from_file(const QString &qmFile)
|
bool lamexp_install_translator_from_file(const QString &qmFile)
|
||||||
{
|
{
|
||||||
|
QWriteLocker writeLock(&g_lamexp_currentTranslator.lock);
|
||||||
bool success = false;
|
bool success = false;
|
||||||
|
|
||||||
if(!g_lamexp_currentTranslator)
|
if(!g_lamexp_currentTranslator.instance.isValid())
|
||||||
{
|
{
|
||||||
g_lamexp_currentTranslator = new QTranslator();
|
g_lamexp_currentTranslator.instance.setValue<QObject*>(new QTranslator());
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!qmFile.isEmpty())
|
if(!qmFile.isEmpty())
|
||||||
{
|
{
|
||||||
QString qmPath = QFileInfo(qmFile).canonicalFilePath();
|
QString qmPath = QFileInfo(qmFile).canonicalFilePath();
|
||||||
QApplication::removeTranslator(g_lamexp_currentTranslator);
|
QTranslator *poTranslator = dynamic_cast<QTranslator*>(g_lamexp_currentTranslator.instance.value<QObject*>());
|
||||||
success = g_lamexp_currentTranslator->load(qmPath);
|
QApplication::removeTranslator(poTranslator);
|
||||||
QApplication::installTranslator(g_lamexp_currentTranslator);
|
if(success = poTranslator->load(qmPath))
|
||||||
if(!success)
|
{
|
||||||
|
QApplication::installTranslator(poTranslator);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
qWarning("Failed to load translation:\n\"%s\"", qmPath.toLatin1().constData());
|
qWarning("Failed to load translation:\n\"%s\"", qmPath.toLatin1().constData());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
QApplication::removeTranslator(g_lamexp_currentTranslator);
|
QApplication::removeTranslator(dynamic_cast<QTranslator*>(g_lamexp_currentTranslator.instance.value<QObject*>()));
|
||||||
success = true;
|
success = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2095,15 +2122,15 @@ void lamexp_finalization(void)
|
|||||||
qDebug("lamexp_finalization()");
|
qDebug("lamexp_finalization()");
|
||||||
|
|
||||||
//Free all tools
|
//Free all tools
|
||||||
if(!g_lamexp_tool_registry.isEmpty())
|
if(!g_lamexp_tools.registry.isEmpty())
|
||||||
{
|
{
|
||||||
QStringList keys = g_lamexp_tool_registry.keys();
|
QStringList keys = g_lamexp_tools.registry.keys();
|
||||||
for(int i = 0; i < keys.count(); i++)
|
for(int i = 0; i < keys.count(); i++)
|
||||||
{
|
{
|
||||||
LAMEXP_DELETE(g_lamexp_tool_registry[keys.at(i)]);
|
LAMEXP_DELETE(g_lamexp_tools.registry[keys.at(i)]);
|
||||||
}
|
}
|
||||||
g_lamexp_tool_registry.clear();
|
g_lamexp_tools.registry.clear();
|
||||||
g_lamexp_tool_versions.clear();
|
g_lamexp_tools.versions.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
//Delete temporary files
|
//Delete temporary files
|
||||||
@ -2121,13 +2148,17 @@ void lamexp_finalization(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Clear languages
|
//Clear languages
|
||||||
if(g_lamexp_currentTranslator)
|
if(g_lamexp_currentTranslator.instance.isValid())
|
||||||
{
|
{
|
||||||
QApplication::removeTranslator(g_lamexp_currentTranslator);
|
QTranslator *poTranslator = dynamic_cast<QTranslator*>(g_lamexp_currentTranslator.instance.value<QObject*>());
|
||||||
LAMEXP_DELETE(g_lamexp_currentTranslator);
|
g_lamexp_currentTranslator.instance.clear();
|
||||||
|
QApplication::removeTranslator(poTranslator);
|
||||||
|
LAMEXP_DELETE(poTranslator);
|
||||||
}
|
}
|
||||||
g_lamexp_translation.files.clear();
|
g_lamexp_translation.files.clear();
|
||||||
g_lamexp_translation.names.clear();
|
g_lamexp_translation.names.clear();
|
||||||
|
g_lamexp_translation.cntry.clear();
|
||||||
|
g_lamexp_translation.sysid.clear();
|
||||||
|
|
||||||
//Destroy Qt application object
|
//Destroy Qt application object
|
||||||
QApplication *application = dynamic_cast<QApplication*>(QApplication::instance());
|
QApplication *application = dynamic_cast<QApplication*>(QApplication::instance());
|
||||||
|
@ -84,7 +84,7 @@ protected:
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
qDebug("Extracting file: %s -> %s", m_toolName.toLatin1().constData(), m_toolShortName.toLatin1().constData());
|
qDebug("Extracting file: %s -> %s", m_toolName.toLatin1().constData(), m_toolShortName.toLatin1().constData());
|
||||||
lockedFile = new LockedFile(QString(":/tools/%1").arg(m_toolName), QString("%1/lamexp_%2").arg(lamexp_temp_folder2(), m_toolShortName), m_toolHash);
|
lockedFile = new LockedFile(QString(":/tools/%1").arg(m_toolName), QString("%1/lxp_%2").arg(lamexp_temp_folder2(), m_toolShortName), m_toolHash);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(lockedFile)
|
if(lockedFile)
|
||||||
|
Loading…
Reference in New Issue
Block a user