Index: ps/trunk/source/lib/file/vfs/vfs.h =================================================================== --- ps/trunk/source/lib/file/vfs/vfs.h +++ ps/trunk/source/lib/file/vfs/vfs.h @@ -78,7 +78,7 @@ }; // (member functions are thread-safe after the instance has been -// constructed - each acquires a pthread mutex.) +// constructed - each acquires a mutex.) struct IVFS { virtual ~IVFS() {} Index: ps/trunk/source/lib/file/vfs/vfs.cpp =================================================================== --- ps/trunk/source/lib/file/vfs/vfs.cpp +++ ps/trunk/source/lib/file/vfs/vfs.cpp @@ -24,7 +24,6 @@ #include "lib/file/vfs/vfs.h" #include "lib/allocators/shared_ptr.h" -#include "lib/posix/posix_pthread.h" #include "lib/file/file_system.h" #include "lib/file/common/file_stats.h" #include "lib/file/common/trace.h" @@ -34,6 +33,9 @@ #include "lib/file/vfs/vfs_lookup.h" #include "lib/file/vfs/vfs_populate.h" +#include +#include + static const StatusDefinition vfsStatusDefinitions[] = { { ERR::VFS_DIR_NOT_FOUND, L"VFS directory not found" }, { ERR::VFS_FILE_NOT_FOUND, L"VFS file not found" }, @@ -41,14 +43,7 @@ }; STATUS_ADD_DEFINITIONS(vfsStatusDefinitions); -static pthread_mutex_t vfs_mutex = PTHREAD_MUTEX_INITIALIZER; -namespace { -struct ScopedLock -{ - ScopedLock() { pthread_mutex_lock(&vfs_mutex); } - ~ScopedLock() { pthread_mutex_unlock(&vfs_mutex); } -}; -} // namespace +static std::mutex vfs_mutex; class VFS : public IVFS { @@ -59,7 +54,7 @@ virtual Status Mount(const VfsPath& mountPoint, const OsPath& path, size_t flags /* = 0 */, size_t priority /* = 0 */) { - ScopedLock s; + std::lock_guard lock(vfs_mutex); if(!DirectoryExists(path)) { if(flags & VFS_MOUNT_MUST_EXIST) @@ -78,7 +73,7 @@ virtual Status GetFileInfo(const VfsPath& pathname, CFileInfo* pfileInfo) const { - ScopedLock s; + std::lock_guard lock(vfs_mutex); VfsDirectory* directory; VfsFile* file; @@ -92,7 +87,7 @@ virtual Status GetFilePriority(const VfsPath& pathname, size_t* ppriority) const { - ScopedLock s; + std::lock_guard lock(vfs_mutex); VfsDirectory* directory; VfsFile* file; RETURN_STATUS_IF_ERR(vfs_Lookup(pathname, &m_rootDirectory, directory, &file)); *ppriority = file->Priority(); @@ -101,7 +96,7 @@ virtual Status GetDirectoryEntries(const VfsPath& path, CFileInfos* fileInfos, DirectoryNames* subdirectoryNames) const { - ScopedLock s; + std::lock_guard lock(vfs_mutex); VfsDirectory* directory; RETURN_STATUS_IF_ERR(vfs_Lookup(path, &m_rootDirectory, directory, 0)); @@ -131,7 +126,7 @@ virtual Status CreateFile(const VfsPath& pathname, const shared_ptr& fileContents, size_t size) { - ScopedLock s; + std::lock_guard lock(vfs_mutex); VfsDirectory* directory; Status st; st = vfs_Lookup(pathname, &m_rootDirectory, directory, 0, VFS_LOOKUP_ADD|VFS_LOOKUP_CREATE|VFS_LOOKUP_CREATE_ALWAYS); @@ -153,7 +148,7 @@ virtual Status ReplaceFile(const VfsPath& pathname, const shared_ptr& fileContents, size_t size) { - ScopedLock s; + std::unique_lock lock(vfs_mutex); VfsDirectory* directory; VfsFile* file; Status st; @@ -162,7 +157,7 @@ // There is no such file, create it. if (st == ERR::VFS_FILE_NOT_FOUND) { - s.~ScopedLock(); + lock.unlock(); return CreateFile(pathname, fileContents, size); } @@ -179,7 +174,7 @@ virtual Status LoadFile(const VfsPath& pathname, shared_ptr& fileContents, size_t& size) { - ScopedLock s; + std::lock_guard lock(vfs_mutex); VfsDirectory* directory; VfsFile* file; // per 2010-05-01 meeting, this shouldn't raise 'scary error @@ -201,7 +196,7 @@ virtual std::wstring TextRepresentation() const { - ScopedLock s; + std::lock_guard lock(vfs_mutex); std::wstring textRepresentation; textRepresentation.reserve(100*KiB); DirectoryDescriptionR(textRepresentation, m_rootDirectory, 0); @@ -210,7 +205,7 @@ virtual Status GetRealPath(const VfsPath& pathname, OsPath& realPathname) { - ScopedLock s; + std::lock_guard lock(vfs_mutex); VfsDirectory* directory; VfsFile* file; WARN_RETURN_STATUS_IF_ERR(vfs_Lookup(pathname, &m_rootDirectory, directory, &file)); realPathname = file->Loader()->Path() / pathname.Filename(); @@ -219,7 +214,7 @@ virtual Status GetDirectoryRealPath(const VfsPath& pathname, OsPath& realPathname) { - ScopedLock s; + std::lock_guard lock(vfs_mutex); VfsDirectory* directory; WARN_RETURN_STATUS_IF_ERR(vfs_Lookup(pathname, &m_rootDirectory, directory, NULL)); realPathname = directory->AssociatedDirectory()->Path(); @@ -228,7 +223,7 @@ virtual Status GetVirtualPath(const OsPath& realPathname, VfsPath& pathname) { - ScopedLock s; + std::lock_guard lock(vfs_mutex); const OsPath realPath = realPathname.Parent()/""; VfsPath path; RETURN_STATUS_IF_ERR(FindRealPathR(realPath, m_rootDirectory, L"", path)); @@ -238,7 +233,7 @@ virtual Status RemoveFile(const VfsPath& pathname) { - ScopedLock s; + std::lock_guard lock(vfs_mutex); VfsDirectory* directory; VfsFile* file; RETURN_STATUS_IF_ERR(vfs_Lookup(pathname, &m_rootDirectory, directory, &file)); @@ -249,7 +244,7 @@ virtual Status RepopulateDirectory(const VfsPath& path) { - ScopedLock s; + std::lock_guard lock(vfs_mutex); VfsDirectory* directory; RETURN_STATUS_IF_ERR(vfs_Lookup(path, &m_rootDirectory, directory, 0)); @@ -260,7 +255,7 @@ virtual void Clear() { - ScopedLock s; + std::lock_guard lock(vfs_mutex); m_rootDirectory.Clear(); } Index: ps/trunk/source/lib/posix/posix.h =================================================================== --- ps/trunk/source/lib/posix/posix.h +++ ps/trunk/source/lib/posix/posix.h @@ -73,7 +73,6 @@ //#include "lib/posix/posix_dlfcn.h" //#include "lib/posix/posix_filesystem.h" //#include "lib/posix/posix_mman.h" -//#include "lib/posix/posix_pthread.h" //#include "lib/posix/posix_time.h" //#include "lib/posix/posix_utsname.h" Index: ps/trunk/source/lib/res/h_mgr.cpp =================================================================== --- ps/trunk/source/lib/res/h_mgr.cpp +++ ps/trunk/source/lib/res/h_mgr.cpp @@ -38,8 +38,8 @@ #include "lib/allocators/overrun_protector.h" #include "lib/allocators/pool.h" #include "lib/module_init.h" -#include "lib/posix/posix_pthread.h" +#include namespace ERR { static const Status H_IDX_INVALID = -120000; // totally invalid @@ -503,22 +503,12 @@ } -static pthread_mutex_t 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); } -}; - +static std::recursive_mutex h_mutex; // 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, ...) { - H_ScopedLock s; + std::lock_guard lock(h_mutex); RETURN_STATUS_IF_ERR(type_validate(type)); @@ -582,7 +572,7 @@ Status h_free(Handle& h, H_Type type) { - H_ScopedLock s; + std::lock_guard lock(h_mutex); // 0-initialized or an error code; don't complain because this // happens often and is harmless. @@ -636,7 +626,7 @@ // TODO: what if iterating through all handles is too slow? Status h_reload(const PIVFS& vfs, const VfsPath& pathname) { - H_ScopedLock s; + std::lock_guard lock(h_mutex); const u32 key = fnv_hash(pathname.string().c_str(), pathname.string().length()*sizeof(pathname.string()[0])); @@ -678,7 +668,7 @@ Handle h_find(H_Type type, uintptr_t key) { - H_ScopedLock s; + std::lock_guard lock(h_mutex); return key_find(key, type); } @@ -692,7 +682,7 @@ // at that point, all (cached) OpenAL resources must be freed. Status h_force_free(Handle h, H_Type type) { - H_ScopedLock s; + std::lock_guard lock(h_mutex); // require valid index; ignore tag; type checked below. HDATA* hd; @@ -743,18 +733,6 @@ 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 INFO::OK; } @@ -767,7 +745,7 @@ // raise a double-free warning unless we ignore it. (#860, #915, #920) ignoreDoubleFree = true; - H_ScopedLock s; + std::lock_guard lock(h_mutex); // 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)) @@ -791,7 +769,7 @@ { ignoreDoubleFree = true; - H_ScopedLock s; + std::lock_guard lock(h_mutex); // 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)) Index: ps/trunk/source/lib/timer.cpp =================================================================== --- ps/trunk/source/lib/timer.cpp +++ ps/trunk/source/lib/timer.cpp @@ -35,7 +35,6 @@ #include // std::stringstream #include "lib/module_init.h" -#include "lib/posix/posix_pthread.h" #include "lib/posix/posix_time.h" #include "lib/sysdep/cpu.h" Index: ps/trunk/source/network/NetServer.h =================================================================== --- ps/trunk/source/network/NetServer.h +++ ps/trunk/source/network/NetServer.h @@ -21,7 +21,6 @@ #include "NetFileTransfer.h" #include "NetHost.h" #include "lib/config2.h" -#include "lib/posix/posix_pthread.h" #include "lib/types.h" #include "scriptinterface/ScriptTypes.h" @@ -29,6 +28,7 @@ #include #include #include +#include class CNetServerSession; class CNetServerTurnManager; @@ -360,15 +360,15 @@ /** * Try to find a UPnP root on the network and setup port forwarding. */ - static void* SetupUPnP(void*); - pthread_t m_UPnPThread; + static void SetupUPnP(); + std::thread m_UPnPThread; #endif - static void* RunThread(void* data); + static void RunThread(CNetServerWorker* data); void Run(); bool RunStep(); - pthread_t m_WorkerThread; + std::thread m_WorkerThread; std::mutex m_WorkerMutex; // protected by m_WorkerMutex Index: ps/trunk/source/network/NetServer.cpp =================================================================== --- ps/trunk/source/network/NetServer.cpp +++ ps/trunk/source/network/NetServer.cpp @@ -156,7 +156,7 @@ } // Wait for it to shut down cleanly - pthread_join(m_WorkerThread, NULL); + m_WorkerThread.join(); } // Clean up resources @@ -200,20 +200,18 @@ m_State = SERVER_STATE_PREGAME; // Launch the worker thread - int ret = pthread_create(&m_WorkerThread, NULL, &RunThread, this); - ENSURE(ret == 0); + m_WorkerThread = std::thread(RunThread, this); #if CONFIG2_MINIUPNPC // Launch the UPnP thread - ret = pthread_create(&m_UPnPThread, NULL, &SetupUPnP, NULL); - ENSURE(ret == 0); + m_UPnPThread = std::thread(SetupUPnP); #endif return true; } #if CONFIG2_MINIUPNPC -void* CNetServerWorker::SetupUPnP(void*) +void CNetServerWorker::SetupUPnP() { // Values we want to set. char psPort[6]; @@ -260,7 +258,7 @@ else { LOGMESSAGE("Net server: upnpDiscover failed and no working cached URL."); - return NULL; + return; } switch (ret) @@ -286,7 +284,7 @@ if (ret != UPNPCOMMAND_SUCCESS) { LOGMESSAGE("Net server: GetExternalIPAddress failed with code %d (%s)", ret, strupnperror(ret)); - return NULL; + return; } LOGMESSAGE("Net server: ExternalIPAddress = %s", externalIPAddress); @@ -297,7 +295,7 @@ { LOGMESSAGE("Net server: AddPortMapping(%s, %s, %s) failed with code %d (%s)", psPort, psPort, internalIPAddress, ret, strupnperror(ret)); - return NULL; + return; } // Check that the port was actually forwarded. @@ -313,7 +311,7 @@ if (ret != UPNPCOMMAND_SUCCESS) { 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)", @@ -329,8 +327,6 @@ FreeUPNPUrls(&urls); freeUPNPDevlist(devlist); - - return NULL; } #endif // CONFIG2_MINIUPNPC @@ -360,13 +356,11 @@ return ok; } -void* CNetServerWorker::RunThread(void* data) +void CNetServerWorker::RunThread(CNetServerWorker* data) { debug_SetThreadName("NetServer"); - static_cast(data)->Run(); - - return NULL; + data->Run(); } void CNetServerWorker::Run()