Index: ps/trunk/source/graphics/MapGenerator.h =================================================================== --- ps/trunk/source/graphics/MapGenerator.h +++ ps/trunk/source/graphics/MapGenerator.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2018 Wildfire Games. +/* Copyright (C) 2019 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -18,13 +18,14 @@ #ifndef INCLUDED_MAPGENERATOR #define INCLUDED_MAPGENERATOR +#include "lib/posix/posix_pthread.h" #include "ps/FileIo.h" -#include "ps/ThreadUtil.h" #include "ps/TemplateLoader.h" #include "scriptinterface/ScriptInterface.h" #include +#include #include #include @@ -147,7 +148,7 @@ bool Run(); pthread_t m_WorkerThread; - CMutex m_WorkerMutex; + std::mutex m_WorkerMutex; }; Index: ps/trunk/source/graphics/MapGenerator.cpp =================================================================== --- ps/trunk/source/graphics/MapGenerator.cpp +++ ps/trunk/source/graphics/MapGenerator.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2018 Wildfire Games. +/* Copyright (C) 2019 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -70,7 +70,7 @@ void CMapGeneratorWorker::Initialize(const VfsPath& scriptFile, const std::string& settings) { - CScopeLock lock(m_WorkerMutex); + std::lock_guard lock(m_WorkerMutex); // Set progress to positive value m_Progress = 1; @@ -100,7 +100,7 @@ if (!self->Run() || self->m_Progress > 0) { // Don't leave progress in an unknown state, if generator failed, set it to -1 - CScopeLock lock(self->m_WorkerMutex); + std::lock_guard lock(self->m_WorkerMutex); self->m_Progress = -1; } @@ -190,13 +190,13 @@ int CMapGeneratorWorker::GetProgress() { - CScopeLock lock(m_WorkerMutex); + std::lock_guard lock(m_WorkerMutex); return m_Progress; } shared_ptr CMapGeneratorWorker::GetResults() { - CScopeLock lock(m_WorkerMutex); + std::lock_guard lock(m_WorkerMutex); return m_MapData; } @@ -211,7 +211,7 @@ CMapGeneratorWorker* self = static_cast(pCxPrivate->pCBData); // Copy results - CScopeLock lock(self->m_WorkerMutex); + std::lock_guard lock(self->m_WorkerMutex); self->m_MapData = self->m_ScriptInterface->WriteStructuredClone(data); self->m_Progress = 0; } @@ -221,7 +221,7 @@ CMapGeneratorWorker* self = static_cast(pCxPrivate->pCBData); // Copy data - CScopeLock lock(self->m_WorkerMutex); + std::lock_guard lock(self->m_WorkerMutex); if (progress >= self->m_Progress) self->m_Progress = progress; Index: ps/trunk/source/network/NetServer.h =================================================================== --- ps/trunk/source/network/NetServer.h +++ ps/trunk/source/network/NetServer.h @@ -21,10 +21,11 @@ #include "NetFileTransfer.h" #include "NetHost.h" #include "lib/config2.h" +#include "lib/posix/posix_pthread.h" #include "lib/types.h" -#include "ps/ThreadUtil.h" #include "scriptinterface/ScriptTypes.h" +#include #include #include #include @@ -368,7 +369,7 @@ bool RunStep(); pthread_t m_WorkerThread; - CMutex m_WorkerMutex; + std::mutex m_WorkerMutex; // protected by m_WorkerMutex bool m_Shutdown; Index: ps/trunk/source/network/NetServer.cpp =================================================================== --- ps/trunk/source/network/NetServer.cpp +++ ps/trunk/source/network/NetServer.cpp @@ -32,7 +32,6 @@ #include "ps/ConfigDB.h" #include "ps/GUID.h" #include "ps/Profile.h" -#include "ps/ThreadUtil.h" #include "scriptinterface/ScriptInterface.h" #include "scriptinterface/ScriptRuntime.h" #include "simulation2/Simulation2.h" @@ -152,7 +151,7 @@ { // Tell the thread to shut down { - CScopeLock lock(m_WorkerMutex); + std::lock_guard lock(m_WorkerMutex); m_Shutdown = true; } @@ -416,7 +415,7 @@ std::vector newTurnLength; { - CScopeLock lock(m_WorkerMutex); + std::lock_guard lock(m_WorkerMutex); if (m_Shutdown) return false; @@ -1594,7 +1593,7 @@ void CNetServer::StartGame() { - CScopeLock lock(m_Worker->m_WorkerMutex); + std::lock_guard lock(m_Worker->m_WorkerMutex); m_Worker->m_StartGameQueue.push_back(true); } @@ -1604,19 +1603,19 @@ // cross-thread way of passing script data std::string attrsJSON = scriptInterface.StringifyJSON(attrs, false); - CScopeLock lock(m_Worker->m_WorkerMutex); + std::lock_guard lock(m_Worker->m_WorkerMutex); m_Worker->m_GameAttributesQueue.push_back(attrsJSON); } void CNetServer::OnLobbyAuth(const CStr& name, const CStr& token) { - CScopeLock lock(m_Worker->m_WorkerMutex); + std::lock_guard lock(m_Worker->m_WorkerMutex); m_Worker->m_LobbyAuthQueue.push_back(std::make_pair(name, token)); } void CNetServer::SetTurnLength(u32 msecs) { - CScopeLock lock(m_Worker->m_WorkerMutex); + std::lock_guard lock(m_Worker->m_WorkerMutex); m_Worker->m_TurnLengthQueue.push_back(msecs); } Index: ps/trunk/source/network/NetStats.h =================================================================== --- ps/trunk/source/network/NetStats.h +++ ps/trunk/source/network/NetStats.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2016 Wildfire Games. +/* Copyright (C) 2019 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -19,7 +19,8 @@ #define INCLUDED_NETSTATS #include "ps/ProfileViewer.h" -#include "ps/ThreadUtil.h" + +#include typedef struct _ENetPeer ENetPeer; typedef struct _ENetHost ENetHost; @@ -53,7 +54,7 @@ const ENetPeer* m_Peer; std::vector m_ColumnDescriptions; - CMutex m_Mutex; + std::mutex m_Mutex; std::vector> m_LatchedData; // protected by m_Mutex }; Index: ps/trunk/source/network/NetStats.cpp =================================================================== --- ps/trunk/source/network/NetStats.cpp +++ ps/trunk/source/network/NetStats.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2016 Wildfire Games. +/* Copyright (C) 2019 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -74,7 +74,7 @@ m_ColumnDescriptions.push_back(ProfileColumn("Value", 80)); else { - CScopeLock lock(m_Mutex); + std::lock_guard lock(m_Mutex); for (size_t i = 0; i < m_LatchedData.size(); ++i) m_ColumnDescriptions.push_back(ProfileColumn("Peer "+CStr::FromUInt(i), 80)); @@ -87,7 +87,7 @@ { // Return latched data, if we have any { - CScopeLock lock(m_Mutex); + std::lock_guard lock(m_Mutex); if (col > 0 && m_LatchedData.size() > col-1 && m_LatchedData[col-1].size() > row) return m_LatchedData[col-1][row]; } @@ -126,7 +126,7 @@ void CNetStatsTable::LatchHostState(const ENetHost* host) { - CScopeLock lock(m_Mutex); + std::lock_guard lock(m_Mutex); #define ROW(id, title, member) \ m_LatchedData[i].push_back(CStr::FromUInt(host->peers[i].member)); Index: ps/trunk/source/ps/CConsole.h =================================================================== --- ps/trunk/source/ps/CConsole.h +++ ps/trunk/source/ps/CConsole.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2015 Wildfire Games. +/* Copyright (C) 2019 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -22,16 +22,16 @@ #ifndef INCLUDED_CCONSOLE #define INCLUDED_CCONSOLE -#include -#include #include #include +#include +#include +#include #include "graphics/ShaderProgramPtr.h" #include "lib/file/vfs/vfs_path.h" #include "lib/input.h" #include "ps/CStr.h" -#include "ps/ThreadUtil.h" class CTextRenderer; @@ -91,7 +91,7 @@ private: // Lock for all state modified by InsertMessage - CMutex m_Mutex; + std::mutex m_Mutex; float m_fX; float m_fY; Index: ps/trunk/source/ps/CConsole.cpp =================================================================== --- ps/trunk/source/ps/CConsole.cpp +++ ps/trunk/source/ps/CConsole.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2016 Wildfire Games. +/* Copyright (C) 2019 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -238,7 +238,7 @@ std::deque::iterator Iter; //History iterator - CScopeLock lock(m_Mutex); // needed for safe access to m_deqMsgHistory + std::lock_guard lock(m_Mutex); // needed for safe access to m_deqMsgHistory textRenderer.Color(1.0f, 1.0f, 1.0f); @@ -381,7 +381,7 @@ case SDLK_HOME: if (g_keys[SDLK_RCTRL] || g_keys[SDLK_LCTRL]) { - CScopeLock lock(m_Mutex); // needed for safe access to m_deqMsgHistory + std::lock_guard lock(m_Mutex); // needed for safe access to m_deqMsgHistory int linesShown = (int)m_fHeight/m_iFontHeight - 4; m_iMsgHistPos = clamp((int)m_deqMsgHistory.size() - linesShown, 1, (int)m_deqMsgHistory.size()); @@ -442,7 +442,7 @@ // BEGIN: Message History Lookup case SDLK_PAGEUP: { - CScopeLock lock(m_Mutex); // needed for safe access to m_deqMsgHistory + std::lock_guard lock(m_Mutex); // needed for safe access to m_deqMsgHistory if (m_iMsgHistPos != (int)m_deqMsgHistory.size()) m_iMsgHistPos++; return; @@ -504,7 +504,7 @@ oldNewline = 0; { - CScopeLock lock(m_Mutex); // needed for safe access to m_deqMsgHistory + std::lock_guard lock(m_Mutex); // needed for safe access to m_deqMsgHistory while ( (distance = wrapAround.find(newline, oldNewline)) != wrapAround.npos) { Index: ps/trunk/source/ps/CLogger.h =================================================================== --- ps/trunk/source/ps/CLogger.h +++ ps/trunk/source/ps/CLogger.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2015 Wildfire Games. +/* Copyright (C) 2019 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -19,11 +19,11 @@ #define INCLUDED_CLOGGER #include +#include #include #include #include -#include "ps/ThreadUtil.h" #include "third_party/cppformat/format.h" class CLogger; @@ -105,7 +105,7 @@ double m_RenderLastEraseTime; // Lock for all state modified by logging commands - CMutex m_Mutex; + std::mutex m_Mutex; }; /** Index: ps/trunk/source/ps/CLogger.cpp =================================================================== --- ps/trunk/source/ps/CLogger.cpp +++ ps/trunk/source/ps/CLogger.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2017 Wildfire Games. +/* Copyright (C) 2019 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -142,7 +142,7 @@ { std::string cmessage = ToHTML(message); - CScopeLock lock(m_Mutex); + std::lock_guard lock(m_Mutex); ++m_NumberOfMessages; // if (m_UseDebugPrintf) @@ -163,7 +163,7 @@ { std::string cmessage = ToHTML(message); - CScopeLock lock(m_Mutex); + std::lock_guard lock(m_Mutex); ++m_NumberOfErrors; if (m_UseDebugPrintf) @@ -183,7 +183,7 @@ { std::string cmessage = ToHTML(message); - CScopeLock lock(m_Mutex); + std::lock_guard lock(m_Mutex); ++m_NumberOfWarnings; if (m_UseDebugPrintf) @@ -221,7 +221,7 @@ // (Lock must come after loading the CFont, since that might log error messages // and attempt to lock the mutex recursively which is forbidden) - CScopeLock lock(m_Mutex); + std::lock_guard lock(m_Mutex); for (const RenderedMessage& msg : m_RenderMessages) { @@ -285,7 +285,7 @@ void CLogger::CleanupRenderQueue() { - CScopeLock lock(m_Mutex); + std::lock_guard lock(m_Mutex); if (m_RenderMessages.empty()) return; Index: ps/trunk/source/ps/ConfigDB.h =================================================================== --- ps/trunk/source/ps/ConfigDB.h +++ ps/trunk/source/ps/ConfigDB.h @@ -53,8 +53,6 @@ class CConfigDB : public Singleton { public: - CConfigDB(); - /** * Attempt to retrieve the value of a config variable with the given name; * will search CFG_COMMAND first, and then all namespaces from the specified Index: ps/trunk/source/ps/ConfigDB.cpp =================================================================== --- ps/trunk/source/ps/ConfigDB.cpp +++ ps/trunk/source/ps/ConfigDB.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2018 Wildfire Games. +/* Copyright (C) 2019 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -26,16 +26,17 @@ #include "ps/CLogger.h" #include "ps/CStr.h" #include "ps/Filesystem.h" -#include "ps/ThreadUtil.h" +#include #include + typedef std::map TConfigMap; TConfigMap CConfigDB::m_Map[CFG_LAST]; VfsPath CConfigDB::m_ConfigFile[CFG_LAST]; bool CConfigDB::m_HasChanges[CFG_LAST]; -static pthread_mutex_t cfgdb_mutex = PTHREAD_MUTEX_INITIALIZER; +static std::recursive_mutex cfgdb_mutex; // These entries will not be printed to logfiles, so that logfiles can be shared without leaking personal or sensitive data static const std::unordered_set g_UnloggedEntries = { @@ -44,21 +45,6 @@ "userreport.id" // authentication token for GDPR personal data requests }; -CConfigDB::CConfigDB() -{ - // Recursive mutex needed for WriteFile - pthread_mutexattr_t attr; - int err; - err = pthread_mutexattr_init(&attr); - ENSURE(err == 0); - err = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); - ENSURE(err == 0); - err = pthread_mutex_init(&cfgdb_mutex, &attr); - ENSURE(err == 0); - err = pthread_mutexattr_destroy(&attr); - ENSURE(err == 0); -} - #define CHECK_NS(rval)\ do {\ if (ns < 0 || ns >= CFG_LAST)\ @@ -102,7 +88,7 @@ void CConfigDB::GetValue(EConfigNamespace ns, const CStr& name, type& value)\ {\ CHECK_NS(;);\ - CScopeLock s(&cfgdb_mutex);\ + std::lock_guard s(cfgdb_mutex);\ TConfigMap::iterator it = m_Map[CFG_COMMAND].find(name);\ if (it != m_Map[CFG_COMMAND].end())\ {\ @@ -131,7 +117,7 @@ { CHECK_NS(false); - CScopeLock s(&cfgdb_mutex); + std::lock_guard s(cfgdb_mutex); return m_HasChanges[ns]; } @@ -139,7 +125,7 @@ { CHECK_NS(;); - CScopeLock s(&cfgdb_mutex); + std::lock_guard s(cfgdb_mutex); m_HasChanges[ns] = value; } @@ -147,7 +133,7 @@ { CHECK_NS(;); - CScopeLock s(&cfgdb_mutex); + std::lock_guard s(cfgdb_mutex); TConfigMap::iterator it = m_Map[CFG_COMMAND].find(name); if (it != m_Map[CFG_COMMAND].end()) { @@ -170,7 +156,7 @@ { CHECK_NS(CFG_LAST); - CScopeLock s(&cfgdb_mutex); + std::lock_guard s(cfgdb_mutex); TConfigMap::iterator it = m_Map[CFG_COMMAND].find(name); if (it != m_Map[CFG_COMMAND].end()) return CFG_COMMAND; @@ -187,7 +173,7 @@ std::map CConfigDB::GetValuesWithPrefix(EConfigNamespace ns, const CStr& prefix) const { - CScopeLock s(&cfgdb_mutex); + std::lock_guard s(cfgdb_mutex); std::map ret; CHECK_NS(ret); @@ -210,7 +196,7 @@ { CHECK_NS(;); - CScopeLock s(&cfgdb_mutex); + std::lock_guard s(cfgdb_mutex); TConfigMap::iterator it = m_Map[ns].find(name); if (it == m_Map[ns].end()) it = m_Map[ns].insert(m_Map[ns].begin(), make_pair(name, CConfigValueSet(1))); @@ -228,7 +214,7 @@ { CHECK_NS(;); - CScopeLock s(&cfgdb_mutex); + std::lock_guard s(cfgdb_mutex); TConfigMap::iterator it = m_Map[ns].find(name); if (it == m_Map[ns].end()) return; @@ -239,7 +225,7 @@ { CHECK_NS(;); - CScopeLock s(&cfgdb_mutex); + std::lock_guard s(cfgdb_mutex); m_ConfigFile[ns] = path; } @@ -247,7 +233,7 @@ { CHECK_NS(false); - CScopeLock s(&cfgdb_mutex); + std::lock_guard s(cfgdb_mutex); shared_ptr buffer; size_t buflen; @@ -410,7 +396,7 @@ { CHECK_NS(false); - CScopeLock s(&cfgdb_mutex); + std::lock_guard s(cfgdb_mutex); return WriteFile(ns, m_ConfigFile[ns]); } @@ -418,7 +404,7 @@ { CHECK_NS(false); - CScopeLock s(&cfgdb_mutex); + std::lock_guard s(cfgdb_mutex); shared_ptr buf; AllocateAligned(buf, 1*MiB, maxSectorSize); char* pos = (char*)buf.get(); @@ -446,7 +432,7 @@ { CHECK_NS(false); - CScopeLock s(&cfgdb_mutex); + std::lock_guard s(cfgdb_mutex); return WriteValueToFile(ns, name, value, m_ConfigFile[ns]); } @@ -454,7 +440,7 @@ { CHECK_NS(false); - CScopeLock s(&cfgdb_mutex); + std::lock_guard s(cfgdb_mutex); TConfigMap newMap; m_Map[ns].swap(newMap); Index: ps/trunk/source/ps/Profile.h =================================================================== --- ps/trunk/source/ps/Profile.h +++ ps/trunk/source/ps/Profile.h @@ -25,9 +25,9 @@ #include #include "lib/adts/ring_buf.h" +#include "lib/posix/posix_pthread.h" #include "ps/Profiler2.h" #include "ps/Singleton.h" -#include "ps/ThreadUtil.h" #include #include @@ -174,46 +174,8 @@ class CProfileSample { public: - CProfileSample(const char* name) - { - if (CProfileManager::IsInitialised()) - { - // The profiler is only safe to use on the main thread - - if(ThreadUtil::IsMainThread()) - g_Profiler.Start(name); - } - } - ~CProfileSample() - { - if (CProfileManager::IsInitialised()) - if(ThreadUtil::IsMainThread()) - g_Profiler.Stop(); - } -}; - -class CProfileSampleScript -{ -public: - CProfileSampleScript( const char* name ) - { - if (CProfileManager::IsInitialised()) - { - // The profiler is only safe to use on the main thread, - // but scripts get run on other threads too so we need to - // conditionally enable the profiler. - // (This usually only gets used in debug mode so performance - // doesn't matter much.) - if (ThreadUtil::IsMainThread()) - g_Profiler.StartScript( name ); - } - } - ~CProfileSampleScript() - { - if (CProfileManager::IsInitialised()) - if (ThreadUtil::IsMainThread()) - g_Profiler.Stop(); - } + CProfileSample(const char* name); + ~CProfileSample(); }; // Put a PROFILE("xyz") block at the start of all code to be profiled. Index: ps/trunk/source/ps/Profile.cpp =================================================================== --- ps/trunk/source/ps/Profile.cpp +++ ps/trunk/source/ps/Profile.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2011 Wildfire Games. +/* Copyright (C) 2019 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -23,6 +23,8 @@ #include "Profile.h" #include "ProfileViewer.h" +#include "ThreadUtil.h" + #include "lib/timer.h" #if OS_WIN && !defined(NDEBUG) @@ -754,3 +756,20 @@ current = root; g_ProfileViewer.AddRootTable(root->display_table, true); } + +CProfileSample::CProfileSample(const char* name) +{ + if (CProfileManager::IsInitialised()) + { + // The profiler is only safe to use on the main thread + if(ThreadUtil::IsMainThread()) + g_Profiler.Start(name); + } +} + +CProfileSample::~CProfileSample() +{ + if (CProfileManager::IsInitialised()) + if(ThreadUtil::IsMainThread()) + g_Profiler.Stop(); +} Index: ps/trunk/source/ps/Profiler2.h =================================================================== --- ps/trunk/source/ps/Profiler2.h +++ ps/trunk/source/ps/Profiler2.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2016 Wildfire Games. +/* Copyright (C) 2019 Wildfire Games. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the @@ -81,6 +81,8 @@ #include "lib/timer.h" #include "ps/ThreadUtil.h" +#include + struct mg_context; // Note: Lots of functions are defined inline, to hypothetically @@ -453,7 +455,7 @@ CProfiler2GPU* m_GPU; - CMutex m_Mutex; + std::mutex m_Mutex; std::vector m_Threads; // thread-safe; protected by m_Mutex }; Index: ps/trunk/source/ps/Profiler2.cpp =================================================================== --- ps/trunk/source/ps/Profiler2.cpp +++ ps/trunk/source/ps/Profiler2.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2018 Wildfire Games. +/* Copyright (C) 2019 Wildfire Games. * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the @@ -297,13 +297,13 @@ void CProfiler2::AddThreadStorage(ThreadStorage* storage) { - CScopeLock lock(m_Mutex); + std::lock_guard lock(m_Mutex); m_Threads.push_back(storage); } void CProfiler2::RemoveThreadStorage(ThreadStorage* storage) { - CScopeLock lock(m_Mutex); + std::lock_guard lock(m_Mutex); m_Threads.erase(std::find(m_Threads.begin(), m_Threads.end(), storage)); } @@ -724,7 +724,7 @@ { TIMER(L"profile2 overview"); - CScopeLock lock(m_Mutex); + std::lock_guard lock(m_Mutex); stream << "{\"threads\":["; for (size_t i = 0; i < m_Threads.size(); ++i) @@ -902,7 +902,7 @@ { TIMER(L"profile2 get buffer"); - CScopeLock lock(m_Mutex); // lock against changes to m_Threads or deletions of ThreadStorage + std::lock_guard lock(m_Mutex); // lock against changes to m_Threads or deletions of ThreadStorage ThreadStorage* storage = NULL; for (size_t i = 0; i < m_Threads.size(); ++i) @@ -940,7 +940,7 @@ std::vector threads; { - CScopeLock lock(m_Mutex); + std::lock_guard lock(m_Mutex); threads = m_Threads; } Index: ps/trunk/source/ps/ThreadUtil.h =================================================================== --- ps/trunk/source/ps/ThreadUtil.h +++ ps/trunk/source/ps/ThreadUtil.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010 Wildfire Games. +/* Copyright (C) 2019 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -18,85 +18,6 @@ #ifndef INCLUDED_THREADUTIL #define INCLUDED_THREADUTIL -#include "lib/posix/posix_pthread.h" - -#ifdef DEBUG_LOCKS - -#define LOCK_MUTEX(_mutex) STMT( \ - printf("pthread_mutex_lock: 1 %p [pid:%d]\n", _mutex, pthread_self()); \ - pthread_mutex_lock(_mutex); \ - printf("pthread_mutex_lock: 2 %p [pid:%d]\n", _mutex, pthread_self()) \ -) -#define UNLOCK_MUTEX(_mutex) STMT( \ - pthread_mutex_unlock(_mutex); \ - printf("pthread_mutex_unlock: %p [pid:%d]\n", _mutex, pthread_self()) \ -) - -#else - -#define LOCK_MUTEX(_mutex) pthread_mutex_lock(_mutex) -#define UNLOCK_MUTEX(_mutex) pthread_mutex_unlock(_mutex) - -#endif - -/** - * A non-recursive mutual exclusion lock. - */ -class CMutex -{ - NONCOPYABLE(CMutex); - - friend class CScopeLock; - -public: - CMutex() - { - int ret = pthread_mutex_init(&m_Mutex, NULL); - ENSURE(ret == 0); - } - - ~CMutex() - { - int ret = pthread_mutex_destroy(&m_Mutex); - ENSURE(ret == 0); - } - -private: - pthread_mutex_t m_Mutex; -}; - -/** - * Locks a CMutex over this object's lifetime. - * The mutexes are non-recursive - a single thread locking a mutex more than once - * results in undefined behaviour. - */ -class CScopeLock -{ - NONCOPYABLE(CScopeLock); - -public: - CScopeLock(pthread_mutex_t* mutex) : - m_Mutex(mutex) - { - LOCK_MUTEX(m_Mutex); - } - - CScopeLock(CMutex& mutex) : - m_Mutex(&mutex.m_Mutex) - { - LOCK_MUTEX(m_Mutex); - } - - ~CScopeLock() - { - UNLOCK_MUTEX(m_Mutex); - } - -private: - pthread_mutex_t* m_Mutex; -}; - - namespace ThreadUtil { Index: ps/trunk/source/ps/ThreadUtil.cpp =================================================================== --- ps/trunk/source/ps/ThreadUtil.cpp +++ ps/trunk/source/ps/ThreadUtil.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2010 Wildfire Games. +/* Copyright (C) 2019 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -17,10 +17,12 @@ #include "precompiled.h" +#include + #include "ThreadUtil.h" static bool g_MainThreadSet; -static pthread_t g_MainThread; +static std::thread::id g_MainThread; bool ThreadUtil::IsMainThread() { @@ -29,11 +31,11 @@ if (!g_MainThreadSet) return true; - return pthread_equal(pthread_self(), g_MainThread) ? true : false; + return g_MainThread == std::this_thread::get_id(); } void ThreadUtil::SetMainThread() { - g_MainThread = pthread_self(); + g_MainThread = std::this_thread::get_id(); g_MainThreadSet = true; } Index: ps/trunk/source/ps/UserReport.cpp =================================================================== --- ps/trunk/source/ps/UserReport.cpp +++ ps/trunk/source/ps/UserReport.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2018 Wildfire Games. +/* Copyright (C) 2019 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -33,6 +33,7 @@ #include "ps/ThreadUtil.h" #include +#include #include #define DEBUG_UPLOADS 0 @@ -161,7 +162,7 @@ */ void SetEnabled(bool enabled) { - CScopeLock lock(m_WorkerMutex); + std::lock_guard lock(m_WorkerMutex); if (enabled != m_Enabled) { m_Enabled = enabled; @@ -181,7 +182,7 @@ bool Shutdown() { { - CScopeLock lock(m_WorkerMutex); + std::lock_guard lock(m_WorkerMutex); m_Shutdown = true; } @@ -200,7 +201,7 @@ */ std::string GetStatus() { - CScopeLock lock(m_WorkerMutex); + std::lock_guard lock(m_WorkerMutex); return m_Status; } @@ -210,7 +211,7 @@ void Submit(const shared_ptr& report) { { - CScopeLock lock(m_WorkerMutex); + std::lock_guard lock(m_WorkerMutex); m_ReportQueue.push_back(report); } @@ -314,19 +315,19 @@ bool GetEnabled() { - CScopeLock lock(m_WorkerMutex); + std::lock_guard lock(m_WorkerMutex); return m_Enabled; } bool GetShutdown() { - CScopeLock lock(m_WorkerMutex); + std::lock_guard lock(m_WorkerMutex); return m_Shutdown; } void SetStatus(const std::string& status) { - CScopeLock lock(m_WorkerMutex); + std::lock_guard lock(m_WorkerMutex); m_Status = status; #if DEBUG_UPLOADS debug_printf(">>> CUserReporterWorker status: %s\n", status.c_str()); @@ -340,7 +341,7 @@ shared_ptr report; { - CScopeLock lock(m_WorkerMutex); + std::lock_guard lock(m_WorkerMutex); if (m_ReportQueue.empty()) return false; report = m_ReportQueue.front(); @@ -381,7 +382,7 @@ // so shut down and stop talking to it (to avoid wasting bandwidth) if (code == 410) { - CScopeLock lock(m_WorkerMutex); + std::lock_guard lock(m_WorkerMutex); m_Shutdown = true; return false; } @@ -401,7 +402,7 @@ // a long interval { - CScopeLock lock(m_WorkerMutex); + std::lock_guard lock(m_WorkerMutex); m_ReportQueue.push_front(report); } @@ -489,7 +490,7 @@ private: // Thread-related members: pthread_t m_WorkerThread; - CMutex m_WorkerMutex; + std::mutex m_WorkerMutex; SDL_sem* m_WorkerSem; // Shared by main thread and worker thread: Index: ps/trunk/source/ps/XML/RelaxNG.cpp =================================================================== --- ps/trunk/source/ps/XML/RelaxNG.cpp +++ ps/trunk/source/ps/XML/RelaxNG.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2015 Wildfire Games. +/* Copyright (C) 2019 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -26,6 +26,7 @@ #include #include +#include TIMER_ADD_CLIENT(xml_validation); @@ -36,11 +37,11 @@ */ class RelaxNGSchema; static std::map > g_SchemaCache; -static CMutex g_SchemaCacheLock; +static std::mutex g_SchemaCacheLock; void ClearSchemaCache() { - CScopeLock lock(g_SchemaCacheLock); + std::lock_guard lock(g_SchemaCacheLock); g_SchemaCache.clear(); } @@ -92,7 +93,7 @@ shared_ptr schema; { - CScopeLock lock(g_SchemaCacheLock); + std::lock_guard lock(g_SchemaCacheLock); std::map >::iterator it = g_SchemaCache.find(grammar); if (it == g_SchemaCache.end()) { Index: ps/trunk/source/ps/XML/Xeromyces.cpp =================================================================== --- ps/trunk/source/ps/XML/Xeromyces.cpp +++ ps/trunk/source/ps/XML/Xeromyces.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -32,7 +33,7 @@ #include -static CMutex g_ValidatorCacheLock; +static std::mutex g_ValidatorCacheLock; static std::map g_ValidatorCache; static bool g_XeromycesStarted = false; @@ -55,7 +56,7 @@ ENSURE(!g_XeromycesStarted); xmlInitParser(); xmlSetStructuredErrorFunc(NULL, &errorHandler); - CScopeLock lock(g_ValidatorCacheLock); + std::lock_guard lock(g_ValidatorCacheLock); g_ValidatorCache.insert(std::make_pair(std::string(), RelaxNGValidator())); g_XeromycesStarted = true; } @@ -65,7 +66,7 @@ ENSURE(g_XeromycesStarted); g_XeromycesStarted = false; ClearSchemaCache(); - CScopeLock lock(g_ValidatorCacheLock); + std::lock_guard lock(g_ValidatorCacheLock); g_ValidatorCache.clear(); xmlSetStructuredErrorFunc(NULL, NULL); xmlCleanupParser(); @@ -82,7 +83,7 @@ return false; } { - CScopeLock lock(g_ValidatorCacheLock); + std::lock_guard lock(g_ValidatorCacheLock); std::map::iterator it = g_ValidatorCache.find(name); if (it != g_ValidatorCache.end()) g_ValidatorCache.erase(it); @@ -93,7 +94,7 @@ bool CXeromyces::ValidateEncoded(const std::string& name, const std::wstring& filename, const std::string& document) { - CScopeLock lock(g_ValidatorCacheLock); + std::lock_guard lock(g_ValidatorCacheLock); return GetValidator(name).ValidateEncoded(filename, document); } @@ -115,7 +116,7 @@ MD5 validatorGrammarHash; { - CScopeLock lock(g_ValidatorCacheLock); + std::lock_guard lock(g_ValidatorCacheLock); validatorGrammarHash = GetValidator(validatorName).GetGrammarHash(); } VfsPath xmbPath; @@ -174,7 +175,7 @@ } { - CScopeLock lock(g_ValidatorCacheLock); + std::lock_guard lock(g_ValidatorCacheLock); RelaxNGValidator& validator = GetValidator(validatorName); if (validator.CanValidate() && !validator.ValidateEncoded(doc)) // For now, log the error and continue, in the future we might fail @@ -229,7 +230,7 @@ } { - CScopeLock lock(g_ValidatorCacheLock); + std::lock_guard lock(g_ValidatorCacheLock); RelaxNGValidator& validator = GetValidator(validatorName); if (validator.CanValidate() && !validator.ValidateEncoded(doc)) // For now, log the error and continue, in the future we might fail Index: ps/trunk/source/soundmanager/SoundManager.h =================================================================== --- ps/trunk/source/soundmanager/SoundManager.h +++ ps/trunk/source/soundmanager/SoundManager.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2017 Wildfire Games. +/* Copyright (C) 2019 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -32,8 +32,9 @@ #include "ps/Profiler2.h" #include "simulation2/system/Entity.h" -#include #include +#include +#include #define AL_CHECK CSoundManager::al_check(__func__, __LINE__) @@ -64,7 +65,7 @@ ISoundItem* m_CurrentTune; ISoundItem* m_CurrentEnvirons; CSoundManagerWorker* m_Worker; - CMutex m_DistressMutex; + std::mutex m_DistressMutex; PlayList* m_PlayListItems; SoundGroupMap m_SoundGroups; Index: ps/trunk/source/soundmanager/SoundManager.cpp =================================================================== --- ps/trunk/source/soundmanager/SoundManager.cpp +++ ps/trunk/source/soundmanager/SoundManager.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2018 Wildfire Games. +/* Copyright (C) 2019 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -63,7 +63,7 @@ bool Shutdown() { { - CScopeLock lock(m_WorkerMutex); + std::lock_guard lock(m_WorkerMutex); m_Shutdown = true; @@ -83,13 +83,13 @@ void addItem(ISoundItem* anItem) { - CScopeLock lock(m_WorkerMutex); + std::lock_guard lock(m_WorkerMutex); m_Items->push_back(anItem); } void CleanupItems() { - CScopeLock lock(m_DeadItemsMutex); + std::lock_guard lock(m_DeadItemsMutex); AL_CHECK; ItemsList::iterator deadItems = m_DeadItems->begin(); while (deadItems != m_DeadItems->end()) @@ -126,7 +126,7 @@ pauseTime = 50; { - CScopeLock workerLock(m_WorkerMutex); + std::lock_guard workerLock(m_WorkerMutex); ItemsList::iterator lstr = m_Items->begin(); ItemsList* nextItemList = new ItemsList; @@ -143,7 +143,7 @@ } else { - CScopeLock deadItemsLock(m_DeadItemsMutex); + std::lock_guard deadItemsLock(m_DeadItemsMutex); m_DeadItems->push_back(*lstr); } ++lstr; @@ -162,15 +162,15 @@ bool GetShutdown() { - CScopeLock lock(m_WorkerMutex); + std::lock_guard lock(m_WorkerMutex); return m_Shutdown; } private: // Thread-related members: pthread_t m_WorkerThread; - CMutex m_WorkerMutex; - CMutex m_DeadItemsMutex; + std::mutex m_WorkerMutex; + std::mutex m_DeadItemsMutex; // Shared by main thread and worker thread: // These variables are all protected by a mutexes @@ -360,7 +360,7 @@ bool CSoundManager::InDistress() { - CScopeLock lock(m_DistressMutex); + std::lock_guard lock(m_DistressMutex); if (m_DistressTime == 0) return false; @@ -377,7 +377,7 @@ void CSoundManager::SetDistressThroughShortage() { - CScopeLock lock(m_DistressMutex); + std::lock_guard lock(m_DistressMutex); // Going into distress for normal reasons @@ -386,7 +386,7 @@ void CSoundManager::SetDistressThroughError() { - CScopeLock lock(m_DistressMutex); + std::lock_guard lock(m_DistressMutex); // Going into distress due to unknown error Index: ps/trunk/source/soundmanager/items/CBufferItem.cpp =================================================================== --- ps/trunk/source/soundmanager/items/CBufferItem.cpp +++ ps/trunk/source/soundmanager/items/CBufferItem.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2015 Wildfire Games. +/* Copyright (C) 2019 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -24,6 +24,8 @@ #include "soundmanager/SoundManager.h" #include "soundmanager/data/SoundData.h" +#include + CBufferItem::CBufferItem(CSoundData* sndData) { ResetVars(); @@ -73,7 +75,7 @@ if (m_LastPlay) { - CScopeLock lock(m_ItemMutex); + std::lock_guard lock(m_ItemMutex); int proc_state; alGetSourcei(m_ALSource, AL_SOURCE_STATE, &proc_state); AL_CHECK; Index: ps/trunk/source/soundmanager/items/CSoundBase.h =================================================================== --- ps/trunk/source/soundmanager/items/CSoundBase.h +++ ps/trunk/source/soundmanager/items/CSoundBase.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2015 Wildfire Games. +/* Copyright (C) 2019 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -23,10 +23,11 @@ #if CONFIG2_AUDIO #include "lib/external_libraries/openal.h" -#include "ps/ThreadUtil.h" #include "soundmanager/data/SoundData.h" #include "soundmanager/items/ISoundItem.h" +#include + class CSoundBase : public ISoundItem { protected: @@ -45,7 +46,7 @@ ALfloat m_StartVolume; ALfloat m_EndVolume; - CMutex m_ItemMutex; + std::mutex m_ItemMutex; public: CSoundBase(); Index: ps/trunk/source/soundmanager/items/CSoundBase.cpp =================================================================== --- ps/trunk/source/soundmanager/items/CSoundBase.cpp +++ ps/trunk/source/soundmanager/items/CSoundBase.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2015 Wildfire Games. +/* Copyright (C) 2019 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -121,7 +121,7 @@ if ( m_ALSource ) { - CScopeLock lock(m_ItemMutex); + std::lock_guard lock(m_ItemMutex); alSourcef(m_ALSource, AL_GAIN, gain); AL_CHECK; } @@ -131,7 +131,7 @@ { if ( m_ALSource ) { - CScopeLock lock(m_ItemMutex); + std::lock_guard lock(m_ItemMutex); alSourcef(m_ALSource, AL_REFERENCE_DISTANCE, 70.0f); AL_CHECK; alSourcef(m_ALSource, AL_MAX_DISTANCE, 200.0); @@ -151,7 +151,7 @@ { if ( m_ALSource ) { - CScopeLock lock(m_ItemMutex); + std::lock_guard lock(m_ItemMutex); AL_CHECK; alSourcef(m_ALSource, AL_CONE_INNER_ANGLE, innerCone); AL_CHECK; @@ -166,7 +166,7 @@ { if ( m_ALSource ) { - CScopeLock lock(m_ItemMutex); + std::lock_guard lock(m_ItemMutex); alSourcef(m_ALSource, AL_PITCH, pitch); AL_CHECK; } @@ -176,7 +176,7 @@ { if ( m_ALSource ) { - CScopeLock lock(m_ItemMutex); + std::lock_guard lock(m_ItemMutex); alSourcefv(m_ALSource, AL_DIRECTION, direction.GetFloatArray()); AL_CHECK; } @@ -187,7 +187,7 @@ { if ( m_ALSource ) { - CScopeLock lock(m_ItemMutex); + std::lock_guard lock(m_ItemMutex); int proc_state; alGetSourcei(m_ALSource, AL_SOURCE_STATE, &proc_state); AL_CHECK; @@ -211,7 +211,7 @@ { if ( m_ALSource != 0 ) { - CScopeLock lock(m_ItemMutex); + std::lock_guard lock(m_ItemMutex); alSourcefv(m_ALSource,AL_POSITION, position.GetFloatArray()); AL_CHECK; } @@ -274,7 +274,7 @@ void CSoundBase::Play() { - CScopeLock lock(m_ItemMutex); + std::lock_guard lock(m_ItemMutex); m_ShouldBePlaying = true; m_IsPaused = false; @@ -349,7 +349,7 @@ m_ShouldBePlaying = false; if (m_ALSource != 0) { - CScopeLock lock(m_ItemMutex); + std::lock_guard lock(m_ItemMutex); AL_CHECK; alSourcei(m_ALSource, AL_LOOPING, AL_FALSE); Index: ps/trunk/source/soundmanager/items/CSoundItem.cpp =================================================================== --- ps/trunk/source/soundmanager/items/CSoundItem.cpp +++ ps/trunk/source/soundmanager/items/CSoundItem.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2015 Wildfire Games. +/* Copyright (C) 2019 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -24,6 +24,8 @@ #include "soundmanager/SoundManager.h" #include "soundmanager/data/SoundData.h" +#include + CSoundItem::CSoundItem() { ResetVars(); @@ -51,7 +53,7 @@ if (m_LastPlay && m_ALSource) { - CScopeLock lock(m_ItemMutex); + std::lock_guard lock(m_ItemMutex); int proc_state; alGetSourcei(m_ALSource, AL_SOURCE_STATE, &proc_state); AL_CHECK; Index: ps/trunk/source/tools/atlas/GameInterface/MessagePasserImpl.h =================================================================== --- ps/trunk/source/tools/atlas/GameInterface/MessagePasserImpl.h +++ ps/trunk/source/tools/atlas/GameInterface/MessagePasserImpl.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2009 Wildfire Games. +/* Copyright (C) 2019 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -20,10 +20,12 @@ #include "MessagePasser.h" -#include "ps/ThreadUtil.h" +#include "lib/posix/posix_pthread.h" #include "ps/CStr.h" #include +#include + class MessagePasserImpl : public AtlasMessage::MessagePasser { NONCOPYABLE(MessagePasserImpl); @@ -39,7 +41,7 @@ void SetTrace(bool t); private: - CMutex m_Mutex; + std::mutex m_Mutex; CStr m_SemaphoreName; sem_t* m_Semaphore; std::queue m_Queue; Index: ps/trunk/source/tools/atlas/GameInterface/MessagePasserImpl.cpp =================================================================== --- ps/trunk/source/tools/atlas/GameInterface/MessagePasserImpl.cpp +++ ps/trunk/source/tools/atlas/GameInterface/MessagePasserImpl.cpp @@ -1,4 +1,4 @@ -/* Copyright (C) 2013 Wildfire Games. +/* Copyright (C) 2019 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -87,7 +87,7 @@ debug_printf("%8.3f add message: %s\n", timer_Time(), msg->GetName()); { - CScopeLock lock(m_Mutex); + std::lock_guard lock(m_Mutex); m_Queue.push(msg); } } @@ -101,7 +101,7 @@ IMessage* msg = NULL; { - CScopeLock lock(m_Mutex); + std::lock_guard lock(m_Mutex); if (! m_Queue.empty()) { msg = m_Queue.front(); @@ -127,7 +127,7 @@ qry->m_Semaphore = static_cast(m_Semaphore); { - CScopeLock lock(m_Mutex); + std::lock_guard lock(m_Mutex); m_Queue.push(qry); } @@ -185,7 +185,7 @@ bool MessagePasserImpl::IsEmpty() { - CScopeLock lock(m_Mutex); + std::lock_guard lock(m_Mutex); return m_Queue.empty(); } Index: ps/trunk/source/tools/atlas/GameInterface/MessagesSetup.h =================================================================== --- ps/trunk/source/tools/atlas/GameInterface/MessagesSetup.h +++ ps/trunk/source/tools/atlas/GameInterface/MessagesSetup.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2009 Wildfire Games. +/* Copyright (C) 2019 Wildfire Games. * This file is part of 0 A.D. * * 0 A.D. is free software: you can redistribute it and/or modify @@ -27,8 +27,6 @@ // Structures in this file are passed over the DLL boundary, so some // carefulness and/or luck is required... -class CMutex; - namespace AtlasMessage {