1
0
forked from 0ad/0ad

pthread -> std::thread (4/7) - Replace pthread in remaining files

This removes pthread mutexes/threads from:
- vfs
- the resource handler manager
- timer
- the network server.

This allows removing it from our general posix include header.

Differential Revision: https://code.wildfiregames.com/D1920
This was SVN commit r22666.
This commit is contained in:
wraitii 2019-08-15 09:07:16 +00:00
parent 9f42c8d6ae
commit 1ff20e8f6a
7 changed files with 44 additions and 79 deletions

View File

@ -24,7 +24,6 @@
#include "lib/file/vfs/vfs.h" #include "lib/file/vfs/vfs.h"
#include "lib/allocators/shared_ptr.h" #include "lib/allocators/shared_ptr.h"
#include "lib/posix/posix_pthread.h"
#include "lib/file/file_system.h" #include "lib/file/file_system.h"
#include "lib/file/common/file_stats.h" #include "lib/file/common/file_stats.h"
#include "lib/file/common/trace.h" #include "lib/file/common/trace.h"
@ -34,6 +33,9 @@
#include "lib/file/vfs/vfs_lookup.h" #include "lib/file/vfs/vfs_lookup.h"
#include "lib/file/vfs/vfs_populate.h" #include "lib/file/vfs/vfs_populate.h"
#include <mutex>
#include <thread>
static const StatusDefinition vfsStatusDefinitions[] = { static const StatusDefinition vfsStatusDefinitions[] = {
{ ERR::VFS_DIR_NOT_FOUND, L"VFS directory not found" }, { ERR::VFS_DIR_NOT_FOUND, L"VFS directory not found" },
{ ERR::VFS_FILE_NOT_FOUND, L"VFS file not found" }, { ERR::VFS_FILE_NOT_FOUND, L"VFS file not found" },
@ -41,14 +43,7 @@ static const StatusDefinition vfsStatusDefinitions[] = {
}; };
STATUS_ADD_DEFINITIONS(vfsStatusDefinitions); STATUS_ADD_DEFINITIONS(vfsStatusDefinitions);
static pthread_mutex_t vfs_mutex = PTHREAD_MUTEX_INITIALIZER; static std::mutex vfs_mutex;
namespace {
struct ScopedLock
{
ScopedLock() { pthread_mutex_lock(&vfs_mutex); }
~ScopedLock() { pthread_mutex_unlock(&vfs_mutex); }
};
} // namespace
class VFS : public IVFS class VFS : public IVFS
{ {
@ -59,7 +54,7 @@ public:
virtual Status Mount(const VfsPath& mountPoint, const OsPath& path, size_t flags /* = 0 */, size_t priority /* = 0 */) virtual Status Mount(const VfsPath& mountPoint, const OsPath& path, size_t flags /* = 0 */, size_t priority /* = 0 */)
{ {
ScopedLock s; std::lock_guard<std::mutex> lock(vfs_mutex);
if(!DirectoryExists(path)) if(!DirectoryExists(path))
{ {
if(flags & VFS_MOUNT_MUST_EXIST) if(flags & VFS_MOUNT_MUST_EXIST)
@ -78,7 +73,7 @@ public:
virtual Status GetFileInfo(const VfsPath& pathname, CFileInfo* pfileInfo) const virtual Status GetFileInfo(const VfsPath& pathname, CFileInfo* pfileInfo) const
{ {
ScopedLock s; std::lock_guard<std::mutex> lock(vfs_mutex);
VfsDirectory* directory; VfsDirectory* directory;
VfsFile* file; VfsFile* file;
@ -92,7 +87,7 @@ public:
virtual Status GetFilePriority(const VfsPath& pathname, size_t* ppriority) const virtual Status GetFilePriority(const VfsPath& pathname, size_t* ppriority) const
{ {
ScopedLock s; std::lock_guard<std::mutex> lock(vfs_mutex);
VfsDirectory* directory; VfsFile* file; VfsDirectory* directory; VfsFile* file;
RETURN_STATUS_IF_ERR(vfs_Lookup(pathname, &m_rootDirectory, directory, &file)); RETURN_STATUS_IF_ERR(vfs_Lookup(pathname, &m_rootDirectory, directory, &file));
*ppriority = file->Priority(); *ppriority = file->Priority();
@ -101,7 +96,7 @@ public:
virtual Status GetDirectoryEntries(const VfsPath& path, CFileInfos* fileInfos, DirectoryNames* subdirectoryNames) const virtual Status GetDirectoryEntries(const VfsPath& path, CFileInfos* fileInfos, DirectoryNames* subdirectoryNames) const
{ {
ScopedLock s; std::lock_guard<std::mutex> lock(vfs_mutex);
VfsDirectory* directory; VfsDirectory* directory;
RETURN_STATUS_IF_ERR(vfs_Lookup(path, &m_rootDirectory, directory, 0)); RETURN_STATUS_IF_ERR(vfs_Lookup(path, &m_rootDirectory, directory, 0));
@ -131,7 +126,7 @@ public:
virtual Status CreateFile(const VfsPath& pathname, const shared_ptr<u8>& fileContents, size_t size) virtual Status CreateFile(const VfsPath& pathname, const shared_ptr<u8>& fileContents, size_t size)
{ {
ScopedLock s; std::lock_guard<std::mutex> lock(vfs_mutex);
VfsDirectory* directory; VfsDirectory* directory;
Status st; Status st;
st = vfs_Lookup(pathname, &m_rootDirectory, directory, 0, VFS_LOOKUP_ADD|VFS_LOOKUP_CREATE|VFS_LOOKUP_CREATE_ALWAYS); st = vfs_Lookup(pathname, &m_rootDirectory, directory, 0, VFS_LOOKUP_ADD|VFS_LOOKUP_CREATE|VFS_LOOKUP_CREATE_ALWAYS);
@ -153,7 +148,7 @@ public:
virtual Status ReplaceFile(const VfsPath& pathname, const shared_ptr<u8>& fileContents, size_t size) virtual Status ReplaceFile(const VfsPath& pathname, const shared_ptr<u8>& fileContents, size_t size)
{ {
ScopedLock s; std::unique_lock<std::mutex> lock(vfs_mutex);
VfsDirectory* directory; VfsDirectory* directory;
VfsFile* file; VfsFile* file;
Status st; Status st;
@ -162,7 +157,7 @@ public:
// There is no such file, create it. // There is no such file, create it.
if (st == ERR::VFS_FILE_NOT_FOUND) if (st == ERR::VFS_FILE_NOT_FOUND)
{ {
s.~ScopedLock(); lock.unlock();
return CreateFile(pathname, fileContents, size); return CreateFile(pathname, fileContents, size);
} }
@ -179,7 +174,7 @@ public:
virtual Status LoadFile(const VfsPath& pathname, shared_ptr<u8>& fileContents, size_t& size) virtual Status LoadFile(const VfsPath& pathname, shared_ptr<u8>& fileContents, size_t& size)
{ {
ScopedLock s; std::lock_guard<std::mutex> lock(vfs_mutex);
VfsDirectory* directory; VfsFile* file; VfsDirectory* directory; VfsFile* file;
// per 2010-05-01 meeting, this shouldn't raise 'scary error // per 2010-05-01 meeting, this shouldn't raise 'scary error
@ -201,7 +196,7 @@ public:
virtual std::wstring TextRepresentation() const virtual std::wstring TextRepresentation() const
{ {
ScopedLock s; std::lock_guard<std::mutex> lock(vfs_mutex);
std::wstring textRepresentation; std::wstring textRepresentation;
textRepresentation.reserve(100*KiB); textRepresentation.reserve(100*KiB);
DirectoryDescriptionR(textRepresentation, m_rootDirectory, 0); DirectoryDescriptionR(textRepresentation, m_rootDirectory, 0);
@ -210,7 +205,7 @@ public:
virtual Status GetRealPath(const VfsPath& pathname, OsPath& realPathname) virtual Status GetRealPath(const VfsPath& pathname, OsPath& realPathname)
{ {
ScopedLock s; std::lock_guard<std::mutex> lock(vfs_mutex);
VfsDirectory* directory; VfsFile* file; VfsDirectory* directory; VfsFile* file;
WARN_RETURN_STATUS_IF_ERR(vfs_Lookup(pathname, &m_rootDirectory, directory, &file)); WARN_RETURN_STATUS_IF_ERR(vfs_Lookup(pathname, &m_rootDirectory, directory, &file));
realPathname = file->Loader()->Path() / pathname.Filename(); realPathname = file->Loader()->Path() / pathname.Filename();
@ -219,7 +214,7 @@ public:
virtual Status GetDirectoryRealPath(const VfsPath& pathname, OsPath& realPathname) virtual Status GetDirectoryRealPath(const VfsPath& pathname, OsPath& realPathname)
{ {
ScopedLock s; std::lock_guard<std::mutex> lock(vfs_mutex);
VfsDirectory* directory; VfsDirectory* directory;
WARN_RETURN_STATUS_IF_ERR(vfs_Lookup(pathname, &m_rootDirectory, directory, NULL)); WARN_RETURN_STATUS_IF_ERR(vfs_Lookup(pathname, &m_rootDirectory, directory, NULL));
realPathname = directory->AssociatedDirectory()->Path(); realPathname = directory->AssociatedDirectory()->Path();
@ -228,7 +223,7 @@ public:
virtual Status GetVirtualPath(const OsPath& realPathname, VfsPath& pathname) virtual Status GetVirtualPath(const OsPath& realPathname, VfsPath& pathname)
{ {
ScopedLock s; std::lock_guard<std::mutex> lock(vfs_mutex);
const OsPath realPath = realPathname.Parent()/""; const OsPath realPath = realPathname.Parent()/"";
VfsPath path; VfsPath path;
RETURN_STATUS_IF_ERR(FindRealPathR(realPath, m_rootDirectory, L"", path)); RETURN_STATUS_IF_ERR(FindRealPathR(realPath, m_rootDirectory, L"", path));
@ -238,7 +233,7 @@ public:
virtual Status RemoveFile(const VfsPath& pathname) virtual Status RemoveFile(const VfsPath& pathname)
{ {
ScopedLock s; std::lock_guard<std::mutex> lock(vfs_mutex);
VfsDirectory* directory; VfsFile* file; VfsDirectory* directory; VfsFile* file;
RETURN_STATUS_IF_ERR(vfs_Lookup(pathname, &m_rootDirectory, directory, &file)); RETURN_STATUS_IF_ERR(vfs_Lookup(pathname, &m_rootDirectory, directory, &file));
@ -249,7 +244,7 @@ public:
virtual Status RepopulateDirectory(const VfsPath& path) virtual Status RepopulateDirectory(const VfsPath& path)
{ {
ScopedLock s; std::lock_guard<std::mutex> lock(vfs_mutex);
VfsDirectory* directory; VfsDirectory* directory;
RETURN_STATUS_IF_ERR(vfs_Lookup(path, &m_rootDirectory, directory, 0)); RETURN_STATUS_IF_ERR(vfs_Lookup(path, &m_rootDirectory, directory, 0));
@ -260,7 +255,7 @@ public:
virtual void Clear() virtual void Clear()
{ {
ScopedLock s; std::lock_guard<std::mutex> lock(vfs_mutex);
m_rootDirectory.Clear(); m_rootDirectory.Clear();
} }

View File

@ -78,7 +78,7 @@ enum VfsMountFlags
}; };
// (member functions are thread-safe after the instance has been // (member functions are thread-safe after the instance has been
// constructed - each acquires a pthread mutex.) // constructed - each acquires a mutex.)
struct IVFS struct IVFS
{ {
virtual ~IVFS() {} virtual ~IVFS() {}

View File

@ -73,7 +73,6 @@ need only be renamed (e.g. _open, _stat).
//#include "lib/posix/posix_dlfcn.h" //#include "lib/posix/posix_dlfcn.h"
//#include "lib/posix/posix_filesystem.h" //#include "lib/posix/posix_filesystem.h"
//#include "lib/posix/posix_mman.h" //#include "lib/posix/posix_mman.h"
//#include "lib/posix/posix_pthread.h"
//#include "lib/posix/posix_time.h" //#include "lib/posix/posix_time.h"
//#include "lib/posix/posix_utsname.h" //#include "lib/posix/posix_utsname.h"

View File

@ -38,8 +38,8 @@
#include "lib/allocators/overrun_protector.h" #include "lib/allocators/overrun_protector.h"
#include "lib/allocators/pool.h" #include "lib/allocators/pool.h"
#include "lib/module_init.h" #include "lib/module_init.h"
#include "lib/posix/posix_pthread.h"
#include <mutex>
namespace ERR { namespace ERR {
static const Status H_IDX_INVALID = -120000; // totally invalid static const Status H_IDX_INVALID = -120000; // totally invalid
@ -503,22 +503,12 @@ fail:
} }
static pthread_mutex_t h_mutex; static std::recursive_mutex h_mutex;
// (the same class is defined in vfs.cpp, but it is easier to
// just duplicate it to avoid having to specify the mutex.
// such a class exists in ps/ThreadUtil.h, but we can't
// take a dependency on that module here.)
struct H_ScopedLock
{
H_ScopedLock() { pthread_mutex_lock(&h_mutex); }
~H_ScopedLock() { pthread_mutex_unlock(&h_mutex); }
};
// any further params are passed to type's init routine // any further params are passed to type's init routine
Handle h_alloc(H_Type type, const PIVFS& vfs, const VfsPath& pathname, size_t flags, ...) Handle h_alloc(H_Type type, const PIVFS& vfs, const VfsPath& pathname, size_t flags, ...)
{ {
H_ScopedLock s; std::lock_guard<std::recursive_mutex> lock(h_mutex);
RETURN_STATUS_IF_ERR(type_validate(type)); RETURN_STATUS_IF_ERR(type_validate(type));
@ -582,7 +572,7 @@ static void h_free_hd(HDATA* hd)
Status h_free(Handle& h, H_Type type) Status h_free(Handle& h, H_Type type)
{ {
H_ScopedLock s; std::lock_guard<std::recursive_mutex> lock(h_mutex);
// 0-initialized or an error code; don't complain because this // 0-initialized or an error code; don't complain because this
// happens often and is harmless. // happens often and is harmless.
@ -636,7 +626,7 @@ VfsPath h_filename(const Handle h)
// TODO: what if iterating through all handles is too slow? // TODO: what if iterating through all handles is too slow?
Status h_reload(const PIVFS& vfs, const VfsPath& pathname) Status h_reload(const PIVFS& vfs, const VfsPath& pathname)
{ {
H_ScopedLock s; std::lock_guard<std::recursive_mutex> lock(h_mutex);
const u32 key = fnv_hash(pathname.string().c_str(), pathname.string().length()*sizeof(pathname.string()[0])); const u32 key = fnv_hash(pathname.string().c_str(), pathname.string().length()*sizeof(pathname.string()[0]));
@ -678,7 +668,7 @@ Status h_reload(const PIVFS& vfs, const VfsPath& pathname)
Handle h_find(H_Type type, uintptr_t key) Handle h_find(H_Type type, uintptr_t key)
{ {
H_ScopedLock s; std::lock_guard<std::recursive_mutex> lock(h_mutex);
return key_find(key, type); return key_find(key, type);
} }
@ -692,7 +682,7 @@ Handle h_find(H_Type type, uintptr_t key)
// at that point, all (cached) OpenAL resources must be freed. // at that point, all (cached) OpenAL resources must be freed.
Status h_force_free(Handle h, H_Type type) Status h_force_free(Handle h, H_Type type)
{ {
H_ScopedLock s; std::lock_guard<std::recursive_mutex> lock(h_mutex);
// require valid index; ignore tag; type checked below. // require valid index; ignore tag; type checked below.
HDATA* hd; HDATA* hd;
@ -743,18 +733,6 @@ static ModuleInitState initState;
static Status Init() static Status Init()
{ {
// lock must be recursive (e.g. h_alloc calls h_find)
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(&h_mutex, &attr);
ENSURE(err == 0);
err = pthread_mutexattr_destroy(&attr);
ENSURE(err == 0);
RETURN_STATUS_IF_ERR(pool_create(&hpool, hdata_cap*sizeof(HDATA), sizeof(HDATA))); RETURN_STATUS_IF_ERR(pool_create(&hpool, hdata_cap*sizeof(HDATA), sizeof(HDATA)));
return INFO::OK; return INFO::OK;
} }
@ -767,7 +745,7 @@ static void Shutdown()
// raise a double-free warning unless we ignore it. (#860, #915, #920) // raise a double-free warning unless we ignore it. (#860, #915, #920)
ignoreDoubleFree = true; ignoreDoubleFree = true;
H_ScopedLock s; std::lock_guard<std::recursive_mutex> lock(h_mutex);
// forcibly close all open handles // forcibly close all open handles
for(HDATA* hd = (HDATA*)hpool.da.base; hd < (HDATA*)(hpool.da.base + hpool.da.pos); hd = (HDATA*)(uintptr_t(hd)+hpool.el_size)) for(HDATA* hd = (HDATA*)hpool.da.base; hd < (HDATA*)(hpool.da.base + hpool.da.pos); hd = (HDATA*)(uintptr_t(hd)+hpool.el_size))
@ -791,7 +769,7 @@ void h_mgr_free_type(const H_Type type)
{ {
ignoreDoubleFree = true; ignoreDoubleFree = true;
H_ScopedLock s; std::lock_guard<std::recursive_mutex> lock(h_mutex);
// forcibly close all open handles of the specified type // forcibly close all open handles of the specified type
for(HDATA* hd = (HDATA*)hpool.da.base; hd < (HDATA*)(hpool.da.base + hpool.da.pos); hd = (HDATA*)(uintptr_t(hd)+hpool.el_size)) for(HDATA* hd = (HDATA*)hpool.da.base; hd < (HDATA*)(hpool.da.base + hpool.da.pos); hd = (HDATA*)(uintptr_t(hd)+hpool.el_size))

View File

@ -35,7 +35,6 @@
#include <sstream> // std::stringstream #include <sstream> // std::stringstream
#include "lib/module_init.h" #include "lib/module_init.h"
#include "lib/posix/posix_pthread.h"
#include "lib/posix/posix_time.h" #include "lib/posix/posix_time.h"
#include "lib/sysdep/cpu.h" #include "lib/sysdep/cpu.h"

View File

@ -156,7 +156,7 @@ CNetServerWorker::~CNetServerWorker()
} }
// Wait for it to shut down cleanly // Wait for it to shut down cleanly
pthread_join(m_WorkerThread, NULL); m_WorkerThread.join();
} }
// Clean up resources // Clean up resources
@ -200,20 +200,18 @@ bool CNetServerWorker::SetupConnection(const u16 port)
m_State = SERVER_STATE_PREGAME; m_State = SERVER_STATE_PREGAME;
// Launch the worker thread // Launch the worker thread
int ret = pthread_create(&m_WorkerThread, NULL, &RunThread, this); m_WorkerThread = std::thread(RunThread, this);
ENSURE(ret == 0);
#if CONFIG2_MINIUPNPC #if CONFIG2_MINIUPNPC
// Launch the UPnP thread // Launch the UPnP thread
ret = pthread_create(&m_UPnPThread, NULL, &SetupUPnP, NULL); m_UPnPThread = std::thread(SetupUPnP);
ENSURE(ret == 0);
#endif #endif
return true; return true;
} }
#if CONFIG2_MINIUPNPC #if CONFIG2_MINIUPNPC
void* CNetServerWorker::SetupUPnP(void*) void CNetServerWorker::SetupUPnP()
{ {
// Values we want to set. // Values we want to set.
char psPort[6]; char psPort[6];
@ -260,7 +258,7 @@ void* CNetServerWorker::SetupUPnP(void*)
else else
{ {
LOGMESSAGE("Net server: upnpDiscover failed and no working cached URL."); LOGMESSAGE("Net server: upnpDiscover failed and no working cached URL.");
return NULL; return;
} }
switch (ret) switch (ret)
@ -286,7 +284,7 @@ void* CNetServerWorker::SetupUPnP(void*)
if (ret != UPNPCOMMAND_SUCCESS) if (ret != UPNPCOMMAND_SUCCESS)
{ {
LOGMESSAGE("Net server: GetExternalIPAddress failed with code %d (%s)", ret, strupnperror(ret)); LOGMESSAGE("Net server: GetExternalIPAddress failed with code %d (%s)", ret, strupnperror(ret));
return NULL; return;
} }
LOGMESSAGE("Net server: ExternalIPAddress = %s", externalIPAddress); LOGMESSAGE("Net server: ExternalIPAddress = %s", externalIPAddress);
@ -297,7 +295,7 @@ void* CNetServerWorker::SetupUPnP(void*)
{ {
LOGMESSAGE("Net server: AddPortMapping(%s, %s, %s) failed with code %d (%s)", LOGMESSAGE("Net server: AddPortMapping(%s, %s, %s) failed with code %d (%s)",
psPort, psPort, internalIPAddress, ret, strupnperror(ret)); psPort, psPort, internalIPAddress, ret, strupnperror(ret));
return NULL; return;
} }
// Check that the port was actually forwarded. // Check that the port was actually forwarded.
@ -313,7 +311,7 @@ void* CNetServerWorker::SetupUPnP(void*)
if (ret != UPNPCOMMAND_SUCCESS) if (ret != UPNPCOMMAND_SUCCESS)
{ {
LOGMESSAGE("Net server: GetSpecificPortMappingEntry() failed with code %d (%s)", ret, strupnperror(ret)); LOGMESSAGE("Net server: GetSpecificPortMappingEntry() failed with code %d (%s)", ret, strupnperror(ret));
return NULL; return;
} }
LOGMESSAGE("Net server: External %s:%s %s is redirected to internal %s:%s (duration=%s)", LOGMESSAGE("Net server: External %s:%s %s is redirected to internal %s:%s (duration=%s)",
@ -329,8 +327,6 @@ void* CNetServerWorker::SetupUPnP(void*)
FreeUPNPUrls(&urls); FreeUPNPUrls(&urls);
freeUPNPDevlist(devlist); freeUPNPDevlist(devlist);
return NULL;
} }
#endif // CONFIG2_MINIUPNPC #endif // CONFIG2_MINIUPNPC
@ -360,13 +356,11 @@ bool CNetServerWorker::Broadcast(const CNetMessage* message, const std::vector<N
return ok; return ok;
} }
void* CNetServerWorker::RunThread(void* data) void CNetServerWorker::RunThread(CNetServerWorker* data)
{ {
debug_SetThreadName("NetServer"); debug_SetThreadName("NetServer");
static_cast<CNetServerWorker*>(data)->Run(); data->Run();
return NULL;
} }
void CNetServerWorker::Run() void CNetServerWorker::Run()

View File

@ -21,7 +21,6 @@
#include "NetFileTransfer.h" #include "NetFileTransfer.h"
#include "NetHost.h" #include "NetHost.h"
#include "lib/config2.h" #include "lib/config2.h"
#include "lib/posix/posix_pthread.h"
#include "lib/types.h" #include "lib/types.h"
#include "scriptinterface/ScriptTypes.h" #include "scriptinterface/ScriptTypes.h"
@ -29,6 +28,7 @@
#include <string> #include <string>
#include <utility> #include <utility>
#include <vector> #include <vector>
#include <thread>
class CNetServerSession; class CNetServerSession;
class CNetServerTurnManager; class CNetServerTurnManager;
@ -360,15 +360,15 @@ private:
/** /**
* Try to find a UPnP root on the network and setup port forwarding. * Try to find a UPnP root on the network and setup port forwarding.
*/ */
static void* SetupUPnP(void*); static void SetupUPnP();
pthread_t m_UPnPThread; std::thread m_UPnPThread;
#endif #endif
static void* RunThread(void* data); static void RunThread(CNetServerWorker* data);
void Run(); void Run();
bool RunStep(); bool RunStep();
pthread_t m_WorkerThread; std::thread m_WorkerThread;
std::mutex m_WorkerMutex; std::mutex m_WorkerMutex;
// protected by m_WorkerMutex // protected by m_WorkerMutex