mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-02-19 02:36:27 +01:00
Replaced Common::Thread with a partial implementation of std::thread. (rvalue references are used if available, <thread> is used if possible) Eliminates the need to use dynamic memory allocation for threads, so it's impossible to forget to delete a thread or set a pointer to NULL. Enables use of type-safe thread functions, no need to cast to and from void*. I've made sure the code compiles in vs08 and tested the functionality of "StdThread.h" on Linux so I'm hoping everything will work :p. In the future "StdThread.h" can be removed (maybe when OS X ships with gcc 4.4 and vs2015 is released :p).
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@6933 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
0371f15c23
commit
2c05c49a04
@ -54,10 +54,9 @@ void AOSound::SoundLoop()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void *soundThread(void *args)
|
void soundThread(AOSound *aosound)
|
||||||
{
|
{
|
||||||
((AOSound *)args)->SoundLoop();
|
aosound->SoundLoop();
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AOSound::Start()
|
bool AOSound::Start()
|
||||||
@ -66,7 +65,7 @@ bool AOSound::Start()
|
|||||||
|
|
||||||
soundSyncEvent.Init();
|
soundSyncEvent.Init();
|
||||||
|
|
||||||
thread = new Common::Thread(soundThread, (void *)this);
|
thread = std::thread(soundThread, this);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,8 +80,7 @@ void AOSound::Stop()
|
|||||||
soundSyncEvent.Set();
|
soundSyncEvent.Set();
|
||||||
|
|
||||||
soundCriticalSection.Enter();
|
soundCriticalSection.Enter();
|
||||||
delete thread;
|
thread.join();
|
||||||
thread = NULL;
|
|
||||||
|
|
||||||
if (device)
|
if (device)
|
||||||
ao_close(device);
|
ao_close(device);
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
class AOSound : public SoundStream
|
class AOSound : public SoundStream
|
||||||
{
|
{
|
||||||
#if defined(HAVE_AO) && HAVE_AO
|
#if defined(HAVE_AO) && HAVE_AO
|
||||||
Common::Thread *thread;
|
std::thread thread;
|
||||||
Common::CriticalSection soundCriticalSection;
|
Common::CriticalSection soundCriticalSection;
|
||||||
Common::Event soundSyncEvent;
|
Common::Event soundSyncEvent;
|
||||||
|
|
||||||
|
@ -91,10 +91,9 @@ bool DSound::WriteDataToBuffer(DWORD dwOffset, // Our own write
|
|||||||
}
|
}
|
||||||
|
|
||||||
// The audio thread.
|
// The audio thread.
|
||||||
THREAD_RETURN soundThread(void* args)
|
void soundThread(DSound* dsound)
|
||||||
{
|
{
|
||||||
(reinterpret_cast<DSound *>(args))->SoundLoop();
|
dsound->SoundLoop();
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DSound::SoundLoop()
|
void DSound::SoundLoop()
|
||||||
@ -138,7 +137,7 @@ bool DSound::Start()
|
|||||||
dsBuffer->Lock(0, bufferSize, (void* *)&p1, &num1, 0, 0, 0);
|
dsBuffer->Lock(0, bufferSize, (void* *)&p1, &num1, 0, 0, 0);
|
||||||
memset(p1, 0, num1);
|
memset(p1, 0, num1);
|
||||||
dsBuffer->Unlock(p1, num1, 0, 0);
|
dsBuffer->Unlock(p1, num1, 0, 0);
|
||||||
thread = new Common::Thread(soundThread, (void *)this);
|
thread = std::thread(soundThread, this);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -179,8 +178,7 @@ void DSound::Stop()
|
|||||||
// kick the thread if it's waiting
|
// kick the thread if it's waiting
|
||||||
soundSyncEvent.Set();
|
soundSyncEvent.Set();
|
||||||
|
|
||||||
delete thread;
|
thread.join();
|
||||||
thread = NULL;
|
|
||||||
dsBuffer->Stop();
|
dsBuffer->Stop();
|
||||||
dsBuffer->Release();
|
dsBuffer->Release();
|
||||||
ds->Release();
|
ds->Release();
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
class DSound : public SoundStream
|
class DSound : public SoundStream
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
Common::Thread *thread;
|
std::thread thread;
|
||||||
Common::EventEx soundSyncEvent;
|
Common::EventEx soundSyncEvent;
|
||||||
void *hWnd;
|
void *hWnd;
|
||||||
|
|
||||||
|
@ -44,8 +44,7 @@ bool OpenALStream::Start()
|
|||||||
if (pContext)
|
if (pContext)
|
||||||
{
|
{
|
||||||
alcMakeContextCurrent(pContext);
|
alcMakeContextCurrent(pContext);
|
||||||
thread = new Common::Thread(
|
thread = std::thread(OpenALStream::ThreadFunc, this);
|
||||||
OpenALStream::ThreadFunc, (void *)this);
|
|
||||||
bReturn = true;
|
bReturn = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -75,8 +74,7 @@ void OpenALStream::Stop()
|
|||||||
// kick the thread if it's waiting
|
// kick the thread if it's waiting
|
||||||
soundSyncEvent.Set();
|
soundSyncEvent.Set();
|
||||||
|
|
||||||
delete thread;
|
thread.join();
|
||||||
thread = NULL;
|
|
||||||
|
|
||||||
alSourceStop(uiSource);
|
alSourceStop(uiSource);
|
||||||
alSourcei(uiSource, AL_BUFFER, 0);
|
alSourcei(uiSource, AL_BUFFER, 0);
|
||||||
@ -123,10 +121,9 @@ void OpenALStream::Clear(bool mute)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
THREAD_RETURN OpenALStream::ThreadFunc(void* args)
|
void OpenALStream::ThreadFunc(OpenALStream* alstream)
|
||||||
{
|
{
|
||||||
(reinterpret_cast<OpenALStream *>(args))->SoundLoop();
|
alstream->SoundLoop();
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenALStream::SoundLoop()
|
void OpenALStream::SoundLoop()
|
||||||
|
@ -58,10 +58,10 @@ public:
|
|||||||
virtual bool usesMixer() const { return true; }
|
virtual bool usesMixer() const { return true; }
|
||||||
virtual void Update();
|
virtual void Update();
|
||||||
|
|
||||||
static THREAD_RETURN ThreadFunc(void* args);
|
static void ThreadFunc(OpenALStream* args);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Common::Thread *thread;
|
std::thread thread;
|
||||||
Common::EventEx soundSyncEvent;
|
Common::EventEx soundSyncEvent;
|
||||||
|
|
||||||
short realtimeBuffer[OAL_MAX_SAMPLES * 2];
|
short realtimeBuffer[OAL_MAX_SAMPLES * 2];
|
||||||
|
@ -845,6 +845,10 @@
|
|||||||
RelativePath=".\Src\stdafx.h"
|
RelativePath=".\Src\stdafx.h"
|
||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\Src\StdThread.h"
|
||||||
|
>
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\Src\StringUtil.cpp"
|
RelativePath=".\Src\StringUtil.cpp"
|
||||||
>
|
>
|
||||||
|
@ -322,6 +322,7 @@
|
|||||||
<ClInclude Include="Src\SDCardUtil.h" />
|
<ClInclude Include="Src\SDCardUtil.h" />
|
||||||
<ClInclude Include="Src\Setup.h" />
|
<ClInclude Include="Src\Setup.h" />
|
||||||
<ClInclude Include="Src\stdafx.h" />
|
<ClInclude Include="Src\stdafx.h" />
|
||||||
|
<ClInclude Include="Src\StdThread.h" />
|
||||||
<ClInclude Include="Src\StringUtil.h" />
|
<ClInclude Include="Src\StringUtil.h" />
|
||||||
<ClInclude Include="Src\svnrev.h" />
|
<ClInclude Include="Src\svnrev.h" />
|
||||||
<ClInclude Include="Src\svnrev_template.h" />
|
<ClInclude Include="Src\svnrev_template.h" />
|
||||||
|
298
Source/Core/Common/Src/StdThread.h
Normal file
298
Source/Core/Common/Src/StdThread.h
Normal file
@ -0,0 +1,298 @@
|
|||||||
|
|
||||||
|
#ifndef STD_THREAD_H_
|
||||||
|
#define STD_THREAD_H_
|
||||||
|
|
||||||
|
#define GCC_VER(x,y,z) ((x) * 10000 + (y) * 100 + (z))
|
||||||
|
#define GCC_VERSION GCC_VER(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__)
|
||||||
|
|
||||||
|
#if GCC_VERSION >= GCC_VER(4,4,0) && __GXX_EXPERIMENTAL_CXX0X__
|
||||||
|
// GCC 4.4 provides <thread>
|
||||||
|
#include <thread>
|
||||||
|
#else
|
||||||
|
|
||||||
|
// partial std::thread implementation for win32/pthread
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
#if (_MSC_VER >= 1600) || (GCC_VERSION >= GCC_VER(4,3,0) && __GXX_EXPERIMENTAL_CXX0X__)
|
||||||
|
#define USE_RVALUE_REFERENCES
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
// WIN32
|
||||||
|
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#include <Windows.h>
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && defined(_MT)
|
||||||
|
// When linking with LIBCMT (the multithreaded C library), Microsoft recommends
|
||||||
|
// using _beginthreadex instead of CreateThread.
|
||||||
|
#define USE_BEGINTHREADEX
|
||||||
|
#include <process.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef USE_BEGINTHREADEX
|
||||||
|
#define THREAD_ID unsigned
|
||||||
|
#define THREAD_RETURN unsigned __stdcall
|
||||||
|
#else
|
||||||
|
#define THREAD_ID DWORD
|
||||||
|
#define THREAD_RETURN DWORD WINAPI
|
||||||
|
#endif
|
||||||
|
#define THREAD_HANDLE HANDLE
|
||||||
|
|
||||||
|
#else
|
||||||
|
// PTHREAD
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#ifndef _POSIX_THREADS
|
||||||
|
#error unsupported platform (no pthreads?)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#define THREAD_ID pthread_t
|
||||||
|
#define THREAD_HANDLE pthread_t
|
||||||
|
#define THREAD_RETURN void*
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace std
|
||||||
|
{
|
||||||
|
|
||||||
|
class thread
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
typedef THREAD_HANDLE native_handle_type;
|
||||||
|
|
||||||
|
class id
|
||||||
|
{
|
||||||
|
friend class thread;
|
||||||
|
public:
|
||||||
|
id() : m_thread(0) {}
|
||||||
|
id(THREAD_ID _id) : m_thread(_id) {}
|
||||||
|
|
||||||
|
bool operator==(const id& rhs) const
|
||||||
|
{
|
||||||
|
return m_thread == rhs.m_thread;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator!=(const id& rhs) const
|
||||||
|
{
|
||||||
|
return !(*this == rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator<(const id& rhs) const
|
||||||
|
{
|
||||||
|
return m_thread < rhs.m_thread;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
THREAD_ID m_thread;
|
||||||
|
};
|
||||||
|
|
||||||
|
// no variadic template support in msvc
|
||||||
|
//template <typename C, typename... A>
|
||||||
|
//thread(C&& func, A&&... args);
|
||||||
|
|
||||||
|
template <typename C>
|
||||||
|
thread(C func)
|
||||||
|
{
|
||||||
|
StartThread(new Func<C>(func));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename C, typename A>
|
||||||
|
thread(C func, A arg)
|
||||||
|
{
|
||||||
|
StartThread(new FuncArg<C, A>(func, arg));
|
||||||
|
}
|
||||||
|
|
||||||
|
thread() /*= default;*/ {}
|
||||||
|
|
||||||
|
#ifdef USE_RVALUE_REFERENCES
|
||||||
|
thread(const thread&) /*= delete*/;
|
||||||
|
|
||||||
|
thread(thread&& other)
|
||||||
|
{
|
||||||
|
#else
|
||||||
|
thread(const thread& t)
|
||||||
|
{
|
||||||
|
// ugly const_cast to get around lack of rvalue references
|
||||||
|
thread& other = const_cast<thread&>(t);
|
||||||
|
#endif
|
||||||
|
swap(other);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef USE_RVALUE_REFERENCES
|
||||||
|
thread& operator=(const thread&) /*= delete*/;
|
||||||
|
|
||||||
|
thread& operator=(thread&& other)
|
||||||
|
{
|
||||||
|
#else
|
||||||
|
thread& operator=(const thread& t)
|
||||||
|
{
|
||||||
|
// ugly const_cast to get around lack of rvalue references
|
||||||
|
thread& other = const_cast<thread&>(t);
|
||||||
|
#endif
|
||||||
|
if (joinable())
|
||||||
|
detach();
|
||||||
|
swap(other);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
~thread()
|
||||||
|
{
|
||||||
|
if (joinable())
|
||||||
|
detach();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool joinable() const
|
||||||
|
{
|
||||||
|
return m_id != id();
|
||||||
|
}
|
||||||
|
|
||||||
|
id get_id() const
|
||||||
|
{
|
||||||
|
return m_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
native_handle_type native_handle()
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
return m_handle;
|
||||||
|
#else
|
||||||
|
return m_id.m_thread;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void join()
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
WaitForSingleObject(m_handle, INFINITE);
|
||||||
|
detach();
|
||||||
|
#else
|
||||||
|
pthread_join(m_id.m_thread, NULL);
|
||||||
|
m_id = id();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void detach()
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
CloseHandle(m_handle);
|
||||||
|
#else
|
||||||
|
pthread_detach(m_id.m_thread);
|
||||||
|
#endif
|
||||||
|
m_id = id();
|
||||||
|
}
|
||||||
|
|
||||||
|
void swap(thread& other)
|
||||||
|
{
|
||||||
|
std::swap(m_id, other.m_id);
|
||||||
|
#ifdef _WIN32
|
||||||
|
std::swap(m_handle, other.m_handle);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned hardware_concurrency()
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
SYSTEM_INFO sysinfo;
|
||||||
|
GetSystemInfo(&sysinfo);
|
||||||
|
return static_cast<unsigned>(sysinfo.dwNumberOfProcessors);
|
||||||
|
#else
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
id m_id;
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
native_handle_type m_handle;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
template <typename F>
|
||||||
|
void StartThread(F* param)
|
||||||
|
{
|
||||||
|
#ifdef USE_BEGINTHREADEX
|
||||||
|
m_handle = (HANDLE)_beginthreadex(NULL, 0, &RunAndDelete<F>, param, 0, &m_id.m_thread);
|
||||||
|
#elif defined(_WIN32)
|
||||||
|
m_handle = CreateThread(NULL, 0, &RunAndDelete<F>, param, 0, &m_id.m_thread);
|
||||||
|
#else
|
||||||
|
pthread_attr_t attr;
|
||||||
|
pthread_attr_init(&attr);
|
||||||
|
pthread_attr_setstacksize(&attr, 1024 * 1024);
|
||||||
|
if (pthread_create(&m_id.m_thread, &attr, &RunAndDelete<F>, param))
|
||||||
|
m_id = id();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename C>
|
||||||
|
class Func
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Func(C _func) : func(_func) {}
|
||||||
|
|
||||||
|
void Run() { func(); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
C const func;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename C, typename A>
|
||||||
|
class FuncArg
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FuncArg(C _func, A _arg) : func(_func), arg(_arg) {}
|
||||||
|
|
||||||
|
void Run() { func(arg); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
C const func;
|
||||||
|
A arg;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename F>
|
||||||
|
static THREAD_RETURN RunAndDelete(void* param)
|
||||||
|
{
|
||||||
|
static_cast<F*>(param)->Run();
|
||||||
|
delete static_cast<F*>(param);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
namespace this_thread
|
||||||
|
{
|
||||||
|
|
||||||
|
inline void yield()
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
Sleep(1);
|
||||||
|
#else
|
||||||
|
usleep(1000 * 1);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
inline thread::id get_id()
|
||||||
|
{
|
||||||
|
#ifdef _WIN32
|
||||||
|
return GetCurrentThreadId();
|
||||||
|
#else
|
||||||
|
return pthread_self();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace this_thread
|
||||||
|
|
||||||
|
} // namespace std
|
||||||
|
|
||||||
|
#undef USE_RVALUE_REFERENCES
|
||||||
|
#undef USE_BEGINTHREADEX
|
||||||
|
#undef THREAD_ID
|
||||||
|
#undef THREAD_RETURN
|
||||||
|
#undef THREAD_HANDLE
|
||||||
|
|
||||||
|
#endif
|
||||||
|
#endif
|
@ -26,17 +26,27 @@
|
|||||||
namespace Common
|
namespace Common
|
||||||
{
|
{
|
||||||
|
|
||||||
int Thread::CurrentId()
|
int CurrentThreadId()
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
return GetCurrentThreadId();
|
return GetCurrentThreadId();
|
||||||
#else
|
#else
|
||||||
return 0;
|
return 0;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
|
||||||
|
void SetThreadAffinity(std::thread::native_handle_type thread, u32 mask)
|
||||||
|
{
|
||||||
|
SetThreadAffinityMask(thread, mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetCurrentThreadAffinity(u32 mask)
|
||||||
|
{
|
||||||
|
SetThreadAffinityMask(GetCurrentThread(), mask);
|
||||||
|
}
|
||||||
|
|
||||||
CriticalSection::CriticalSection(int spincount)
|
CriticalSection::CriticalSection(int spincount)
|
||||||
{
|
{
|
||||||
if (spincount)
|
if (spincount)
|
||||||
@ -70,54 +80,6 @@ namespace Common
|
|||||||
LeaveCriticalSection(§ion);
|
LeaveCriticalSection(§ion);
|
||||||
}
|
}
|
||||||
|
|
||||||
Thread::Thread(ThreadFunc function, void* arg)
|
|
||||||
: m_hThread(NULL), m_threadId(0)
|
|
||||||
{
|
|
||||||
#ifdef USE_BEGINTHREADEX
|
|
||||||
m_hThread = (HANDLE)_beginthreadex(NULL, 0, function, arg, 0, &m_threadId);
|
|
||||||
#else
|
|
||||||
m_hThread = CreateThread(NULL, 0, function, arg, 0, &m_threadId);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
Thread::~Thread()
|
|
||||||
{
|
|
||||||
WaitForDeath();
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD Thread::WaitForDeath(const int iWait)
|
|
||||||
{
|
|
||||||
if (m_hThread)
|
|
||||||
{
|
|
||||||
DWORD Wait = WaitForSingleObject(m_hThread, iWait);
|
|
||||||
CloseHandle(m_hThread);
|
|
||||||
m_hThread = NULL;
|
|
||||||
return Wait;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Thread::SetAffinity(int mask)
|
|
||||||
{
|
|
||||||
SetThreadAffinityMask(m_hThread, mask);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Thread::SetPriority(int priority)
|
|
||||||
{
|
|
||||||
SetThreadPriority(m_hThread, priority);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Thread::SetCurrentThreadAffinity(int mask)
|
|
||||||
{
|
|
||||||
SetThreadAffinityMask(GetCurrentThread(), mask);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Thread::IsCurrentThread()
|
|
||||||
{
|
|
||||||
return GetCurrentThreadId() == m_threadId;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
EventEx::EventEx()
|
EventEx::EventEx()
|
||||||
{
|
{
|
||||||
InterlockedExchange(&m_Lock, 1);
|
InterlockedExchange(&m_Lock, 1);
|
||||||
@ -301,6 +263,31 @@ namespace Common
|
|||||||
|
|
||||||
#else // !WIN32, so must be POSIX threads
|
#else // !WIN32, so must be POSIX threads
|
||||||
|
|
||||||
|
void LinuxSetThreadAffinity(pthread_t thread, u32 mask)
|
||||||
|
{
|
||||||
|
// This is non-standard
|
||||||
|
#ifdef __linux__
|
||||||
|
cpu_set_t cpu_set;
|
||||||
|
CPU_ZERO(&cpu_set);
|
||||||
|
|
||||||
|
for (int i = 0; i != sizeof(mask) * 8; ++i)
|
||||||
|
if ((mask >> i) & 1)
|
||||||
|
CPU_SET(i, &cpu_set);
|
||||||
|
|
||||||
|
pthread_setaffinity_np(thread, sizeof(cpu_set), &cpu_set);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetThreadAffinity(std::thread::native_handle_type thread, u32 mask)
|
||||||
|
{
|
||||||
|
LinuxSetThreadAffinity(thread, mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetCurrentThreadAffinity(u32 mask)
|
||||||
|
{
|
||||||
|
LinuxSetThreadAffinity(pthread_self(), mask);
|
||||||
|
}
|
||||||
|
|
||||||
static pthread_key_t threadname_key;
|
static pthread_key_t threadname_key;
|
||||||
static pthread_once_t threadname_key_once = PTHREAD_ONCE_INIT;
|
static pthread_once_t threadname_key_once = PTHREAD_ONCE_INIT;
|
||||||
|
|
||||||
@ -345,82 +332,6 @@ namespace Common
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Thread::Thread(ThreadFunc function, void* arg)
|
|
||||||
: thread_id(0)
|
|
||||||
{
|
|
||||||
pthread_attr_t attr;
|
|
||||||
pthread_attr_init(&attr);
|
|
||||||
pthread_attr_setstacksize(&attr, 1024 * 1024);
|
|
||||||
int ret = pthread_create(&thread_id, &attr, function, arg);
|
|
||||||
if (ret) ERROR_LOG(COMMON, "%s: pthread_create(%p, %p, %p, %p) failed: %s\n",
|
|
||||||
__FUNCTION__, &thread_id, &attr, function, arg, strerror(ret));
|
|
||||||
|
|
||||||
INFO_LOG(COMMON, "created new thread %lu (func=%p, arg=%p)\n",
|
|
||||||
(unsigned long)thread_id, function, arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Thread::~Thread()
|
|
||||||
{
|
|
||||||
WaitForDeath();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Thread::WaitForDeath()
|
|
||||||
{
|
|
||||||
if (thread_id)
|
|
||||||
{
|
|
||||||
void* exit_status;
|
|
||||||
int ret = pthread_join(thread_id, &exit_status);
|
|
||||||
if (ret) ERROR_LOG(COMMON,
|
|
||||||
"error joining thread %lu: %s\n",
|
|
||||||
(unsigned long)thread_id, strerror(ret));
|
|
||||||
if (exit_status)
|
|
||||||
ERROR_LOG(COMMON,
|
|
||||||
"thread %lu exited with status %d\n",
|
|
||||||
(unsigned long)thread_id, *(int *)exit_status);
|
|
||||||
thread_id = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Thread::SetAffinity(int mask)
|
|
||||||
{
|
|
||||||
// This is non-standard
|
|
||||||
#ifdef __linux__
|
|
||||||
cpu_set_t cpu_set;
|
|
||||||
CPU_ZERO(&cpu_set);
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < sizeof(mask) * 8; i++)
|
|
||||||
{
|
|
||||||
if ((mask >> i) & 1){CPU_SET(i, &cpu_set);}
|
|
||||||
}
|
|
||||||
|
|
||||||
pthread_setaffinity_np(thread_id, sizeof(cpu_set), &cpu_set);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void Thread::SetCurrentThreadAffinity(int mask)
|
|
||||||
{
|
|
||||||
#ifdef __linux__
|
|
||||||
cpu_set_t cpu_set;
|
|
||||||
CPU_ZERO(&cpu_set);
|
|
||||||
|
|
||||||
for (size_t i = 0; i < sizeof(mask) * 8; i++)
|
|
||||||
{
|
|
||||||
if ((mask >> i) & 1){CPU_SET(i, &cpu_set);}
|
|
||||||
}
|
|
||||||
|
|
||||||
pthread_setaffinity_np(pthread_self(), sizeof(cpu_set), &cpu_set);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Thread::IsCurrentThread()
|
|
||||||
{
|
|
||||||
return pthread_equal(pthread_self(), thread_id) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SleepCurrentThread(int ms)
|
void SleepCurrentThread(int ms)
|
||||||
{
|
{
|
||||||
usleep(1000 * ms);
|
usleep(1000 * ms);
|
||||||
|
@ -18,37 +18,7 @@
|
|||||||
#ifndef _THREAD_H_
|
#ifndef _THREAD_H_
|
||||||
#define _THREAD_H_
|
#define _THREAD_H_
|
||||||
|
|
||||||
#ifdef _WIN32
|
#include "StdThread.h"
|
||||||
|
|
||||||
#if defined(_MSC_VER) && defined(_MT)
|
|
||||||
// When linking with LIBCMT (the multithreaded C library), Microsoft recommends
|
|
||||||
// using _beginthreadex instead of CreateThread.
|
|
||||||
#define USE_BEGINTHREADEX
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define WIN32_LEAN_AND_MEAN
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
#ifdef USE_BEGINTHREADEX
|
|
||||||
#define THREAD_RETURN unsigned __stdcall
|
|
||||||
#else
|
|
||||||
#define THREAD_RETURN DWORD WINAPI
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#include <xmmintrin.h>
|
|
||||||
#define THREAD_RETURN void*
|
|
||||||
#include <unistd.h>
|
|
||||||
#ifdef _POSIX_THREADS
|
|
||||||
#include <pthread.h>
|
|
||||||
#elif GEKKO
|
|
||||||
#include <ogc/lwp_threads.h>
|
|
||||||
#else
|
|
||||||
#error unsupported platform (no pthreads?)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Don't include common.h here as it will break LogManager
|
// Don't include common.h here as it will break LogManager
|
||||||
#include "CommonTypes.h"
|
#include "CommonTypes.h"
|
||||||
@ -61,6 +31,8 @@
|
|||||||
#define INFINITE 0xffffffff
|
#define INFINITE 0xffffffff
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <xmmintrin.h>
|
||||||
|
|
||||||
//for gettimeofday and struct time(spec|val)
|
//for gettimeofday and struct time(spec|val)
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
@ -70,6 +42,11 @@
|
|||||||
namespace Common
|
namespace Common
|
||||||
{
|
{
|
||||||
|
|
||||||
|
int CurrentThreadId();
|
||||||
|
|
||||||
|
void SetThreadAffinity(std::thread::native_handle_type thread, u32 mask);
|
||||||
|
void SetCurrentThreadAffinity(u32 mask);
|
||||||
|
|
||||||
class CriticalSection
|
class CriticalSection
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
@ -88,57 +65,6 @@ namespace Common
|
|||||||
void Leave();
|
void Leave();
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
|
|
||||||
#ifdef USE_BEGINTHREADEX
|
|
||||||
typedef unsigned (__stdcall *ThreadFunc)(void* arg);
|
|
||||||
#else
|
|
||||||
typedef DWORD (WINAPI *ThreadFunc)(void* arg);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
typedef void* (*ThreadFunc)(void* arg);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
class Thread
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
Thread(ThreadFunc entry, void* arg);
|
|
||||||
~Thread();
|
|
||||||
|
|
||||||
void SetAffinity(int mask);
|
|
||||||
static void SetCurrentThreadAffinity(int mask);
|
|
||||||
static int CurrentId();
|
|
||||||
bool IsCurrentThread();
|
|
||||||
#ifdef _WIN32
|
|
||||||
void SetPriority(int priority);
|
|
||||||
DWORD WaitForDeath(const int iWait = INFINITE);
|
|
||||||
#else
|
|
||||||
void WaitForDeath();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
|
|
||||||
HANDLE m_hThread;
|
|
||||||
#ifdef USE_BEGINTHREADEX
|
|
||||||
unsigned m_threadId;
|
|
||||||
#else
|
|
||||||
DWORD m_threadId;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#ifdef _POSIX_THREADS
|
|
||||||
pthread_t thread_id;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
// Event(WaitForSingleObject) is too expensive
|
// Event(WaitForSingleObject) is too expensive
|
||||||
// as it always enters Ring0 regardless of the state of lock
|
// as it always enters Ring0 regardless of the state of lock
|
||||||
|
@ -95,7 +95,7 @@ TPeekMessages Callback_PeekMessages = NULL;
|
|||||||
TUpdateFPSDisplay g_pUpdateFPSDisplay = NULL;
|
TUpdateFPSDisplay g_pUpdateFPSDisplay = NULL;
|
||||||
|
|
||||||
// Function declarations
|
// Function declarations
|
||||||
THREAD_RETURN EmuThread(void *pArg);
|
void EmuThread();
|
||||||
|
|
||||||
void Stop();
|
void Stop();
|
||||||
|
|
||||||
@ -104,9 +104,9 @@ bool g_bHwInit = false;
|
|||||||
bool g_bRealWiimote = false;
|
bool g_bRealWiimote = false;
|
||||||
void *g_pWindowHandle = NULL;
|
void *g_pWindowHandle = NULL;
|
||||||
|
|
||||||
Common::Thread* g_EmuThread = NULL;
|
std::thread g_EmuThread;
|
||||||
|
|
||||||
static Common::Thread* cpuThread = NULL;
|
static std::thread cpuThread;
|
||||||
|
|
||||||
SCoreStartupParameter g_CoreStartupParameter;
|
SCoreStartupParameter g_CoreStartupParameter;
|
||||||
|
|
||||||
@ -122,7 +122,7 @@ Common::Event cpuRunloopQuit;
|
|||||||
std::string StopMessage(bool bMainThread, std::string Message)
|
std::string StopMessage(bool bMainThread, std::string Message)
|
||||||
{
|
{
|
||||||
return StringFromFormat("Stop [%s %i]\t%s\t%s",
|
return StringFromFormat("Stop [%s %i]\t%s\t%s",
|
||||||
bMainThread ? "Main Thread" : "Video Thread", Common::Thread::CurrentId(), MemUsage().c_str(), Message.c_str());
|
bMainThread ? "Main Thread" : "Video Thread", Common::CurrentThreadId(), MemUsage().c_str(), Message.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -166,14 +166,14 @@ bool isRunning()
|
|||||||
|
|
||||||
bool IsRunningInCurrentThread()
|
bool IsRunningInCurrentThread()
|
||||||
{
|
{
|
||||||
return isRunning() && ((cpuThread == NULL) || cpuThread->IsCurrentThread());
|
return isRunning() && ((cpuThread.joinable()) || cpuThread.get_id() == std::this_thread::get_id());
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is called from the GUI thread. See the booting call schedule in
|
// This is called from the GUI thread. See the booting call schedule in
|
||||||
// BootManager.cpp
|
// BootManager.cpp
|
||||||
bool Init()
|
bool Init()
|
||||||
{
|
{
|
||||||
if (g_EmuThread != NULL)
|
if (g_EmuThread.joinable())
|
||||||
{
|
{
|
||||||
PanicAlertT("Emu Thread already running");
|
PanicAlertT("Emu Thread already running");
|
||||||
return false;
|
return false;
|
||||||
@ -195,7 +195,7 @@ bool Init()
|
|||||||
emuThreadGoing.Init();
|
emuThreadGoing.Init();
|
||||||
|
|
||||||
// Start the emu thread
|
// Start the emu thread
|
||||||
g_EmuThread = new Common::Thread(EmuThread, NULL);
|
g_EmuThread = std::thread(EmuThread);
|
||||||
|
|
||||||
// Wait until the emu thread is running
|
// Wait until the emu thread is running
|
||||||
emuThreadGoing.MsgWait();
|
emuThreadGoing.MsgWait();
|
||||||
@ -242,14 +242,12 @@ void Stop() // - Hammertime!
|
|||||||
Host_SetWaitCursor(false);
|
Host_SetWaitCursor(false);
|
||||||
|
|
||||||
WARN_LOG(CONSOLE, "%s", StopMessage(true, "Stopping Emu thread ...").c_str());
|
WARN_LOG(CONSOLE, "%s", StopMessage(true, "Stopping Emu thread ...").c_str());
|
||||||
g_EmuThread->WaitForDeath();
|
g_EmuThread.join(); // Wait for emuthread to close.
|
||||||
delete g_EmuThread; // Wait for emuthread to close.
|
|
||||||
g_EmuThread = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the CPU thread. which would be a CPU + Video thread in Single Core mode.
|
// Create the CPU thread. which would be a CPU + Video thread in Single Core mode.
|
||||||
|
|
||||||
THREAD_RETURN CpuThread(void *pArg)
|
void CpuThread()
|
||||||
{
|
{
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||||
@ -269,7 +267,7 @@ THREAD_RETURN CpuThread(void *pArg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (_CoreParameter.bLockThreads)
|
if (_CoreParameter.bLockThreads)
|
||||||
Common::Thread::SetCurrentThreadAffinity(1); // Force to first core
|
Common::SetCurrentThreadAffinity(1); // Force to first core
|
||||||
|
|
||||||
if (_CoreParameter.bUseFastMem)
|
if (_CoreParameter.bUseFastMem)
|
||||||
{
|
{
|
||||||
@ -296,13 +294,13 @@ THREAD_RETURN CpuThread(void *pArg)
|
|||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
[pool release];
|
[pool release];
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Initalize plugins and create emulation thread
|
// Initalize plugins and create emulation thread
|
||||||
// Call browser: Init():g_EmuThread(). See the BootManager.cpp file description for a complete call schedule.
|
// Call browser: Init():g_EmuThread(). See the BootManager.cpp file description for a complete call schedule.
|
||||||
THREAD_RETURN EmuThread(void *pArg)
|
void EmuThread()
|
||||||
{
|
{
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||||
@ -319,9 +317,9 @@ THREAD_RETURN EmuThread(void *pArg)
|
|||||||
if (_CoreParameter.bLockThreads)
|
if (_CoreParameter.bLockThreads)
|
||||||
{
|
{
|
||||||
if (cpu_info.num_cores > 3)
|
if (cpu_info.num_cores > 3)
|
||||||
Common::Thread::SetCurrentThreadAffinity(4); // Force to third, non-HT core
|
Common::SetCurrentThreadAffinity(4); // Force to third, non-HT core
|
||||||
else
|
else
|
||||||
Common::Thread::SetCurrentThreadAffinity(2); // Force to second core
|
Common::SetCurrentThreadAffinity(2); // Force to second core
|
||||||
}
|
}
|
||||||
|
|
||||||
INFO_LOG(OSREPORT, "Starting core = %s mode", _CoreParameter.bWii ? "Wii" : "Gamecube");
|
INFO_LOG(OSREPORT, "Starting core = %s mode", _CoreParameter.bWii ? "Wii" : "Gamecube");
|
||||||
@ -420,7 +418,7 @@ THREAD_RETURN EmuThread(void *pArg)
|
|||||||
PowerPC::SetMode(PowerPC::MODE_INTERPRETER);
|
PowerPC::SetMode(PowerPC::MODE_INTERPRETER);
|
||||||
|
|
||||||
// Spawn the CPU thread
|
// Spawn the CPU thread
|
||||||
_dbg_assert_(OSHLE, cpuThread == NULL);
|
_dbg_assert_(OSHLE, !cpuThread.joinable());
|
||||||
// ENTER THE VIDEO THREAD LOOP
|
// ENTER THE VIDEO THREAD LOOP
|
||||||
if (_CoreParameter.bCPUThread)
|
if (_CoreParameter.bCPUThread)
|
||||||
{
|
{
|
||||||
@ -428,7 +426,7 @@ THREAD_RETURN EmuThread(void *pArg)
|
|||||||
// and then takes over and becomes the video thread
|
// and then takes over and becomes the video thread
|
||||||
|
|
||||||
Plugins.GetVideo()->Video_Prepare(); // wglMakeCurrent
|
Plugins.GetVideo()->Video_Prepare(); // wglMakeCurrent
|
||||||
cpuThread = new Common::Thread(CpuThread, pArg);
|
cpuThread = std::thread(CpuThread);
|
||||||
Common::SetCurrentThreadName("Video thread");
|
Common::SetCurrentThreadName("Video thread");
|
||||||
|
|
||||||
// Update the window again because all stuff is initialized
|
// Update the window again because all stuff is initialized
|
||||||
@ -444,7 +442,7 @@ THREAD_RETURN EmuThread(void *pArg)
|
|||||||
// Without this extra thread, the video plugin window hangs in single
|
// Without this extra thread, the video plugin window hangs in single
|
||||||
// core mode since noone is pumping messages.
|
// core mode since noone is pumping messages.
|
||||||
|
|
||||||
cpuThread = new Common::Thread(CpuThread, pArg);
|
cpuThread = std::thread(CpuThread);
|
||||||
Common::SetCurrentThreadName("Emuthread - Idle");
|
Common::SetCurrentThreadName("Emuthread - Idle");
|
||||||
|
|
||||||
// Update the window again because all stuff is initialized
|
// Update the window again because all stuff is initialized
|
||||||
@ -475,13 +473,10 @@ THREAD_RETURN EmuThread(void *pArg)
|
|||||||
|
|
||||||
// At this point, the CpuThread has already returned in SC mode.
|
// At this point, the CpuThread has already returned in SC mode.
|
||||||
// But it may still be waiting in Dual Core mode.
|
// But it may still be waiting in Dual Core mode.
|
||||||
if (cpuThread)
|
if (cpuThread.joinable())
|
||||||
{
|
{
|
||||||
// There is a CPU thread - join it.
|
// There is a CPU thread - join it.
|
||||||
cpuThread->WaitForDeath();
|
cpuThread.join();
|
||||||
delete cpuThread;
|
|
||||||
// Returns after game exited
|
|
||||||
cpuThread = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VolumeHandler::EjectVolume();
|
VolumeHandler::EjectVolume();
|
||||||
@ -517,7 +512,6 @@ THREAD_RETURN EmuThread(void *pArg)
|
|||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
[pool release];
|
[pool release];
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set or get the running state
|
// Set or get the running state
|
||||||
|
@ -19,45 +19,41 @@
|
|||||||
#include "EXI_DeviceGecko.h"
|
#include "EXI_DeviceGecko.h"
|
||||||
#include "../Core.h"
|
#include "../Core.h"
|
||||||
|
|
||||||
THREAD_RETURN ClientThreadFunc(void *arg)
|
void ClientThreadFunc(GeckoSockServer *arg)
|
||||||
{
|
{
|
||||||
((GeckoSockServer*)arg)->ClientThread();
|
arg->ClientThread();
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
u16 GeckoSockServer::server_port;
|
u16 GeckoSockServer::server_port;
|
||||||
int GeckoSockServer::client_count;
|
int GeckoSockServer::client_count;
|
||||||
Common::Thread *GeckoSockServer::connectionThread = NULL;
|
std::thread GeckoSockServer::connectionThread;
|
||||||
volatile bool GeckoSockServer::server_running;
|
volatile bool GeckoSockServer::server_running;
|
||||||
std::queue<sf::SocketTCP> GeckoSockServer::waiting_socks;
|
std::queue<sf::SocketTCP> GeckoSockServer::waiting_socks;
|
||||||
Common::CriticalSection GeckoSockServer::connection_lock;
|
Common::CriticalSection GeckoSockServer::connection_lock;
|
||||||
|
|
||||||
GeckoSockServer::GeckoSockServer()
|
GeckoSockServer::GeckoSockServer()
|
||||||
: clientThread(NULL)
|
: client_running(false)
|
||||||
, client_running(false)
|
|
||||||
{
|
{
|
||||||
if (!connectionThread)
|
if (!connectionThread.joinable())
|
||||||
connectionThread = new Common::Thread(&GeckoConnectionWaiter, (void*)0);
|
connectionThread = std::thread(GeckoConnectionWaiter);
|
||||||
}
|
}
|
||||||
|
|
||||||
GeckoSockServer::~GeckoSockServer()
|
GeckoSockServer::~GeckoSockServer()
|
||||||
{
|
{
|
||||||
if (clientThread)
|
if (clientThread.joinable())
|
||||||
--client_count;
|
--client_count;
|
||||||
|
|
||||||
client_running = false;
|
client_running = false;
|
||||||
delete clientThread;
|
clientThread.join();
|
||||||
clientThread = NULL;
|
|
||||||
|
|
||||||
if (client_count <= 0)
|
if (client_count <= 0)
|
||||||
{
|
{
|
||||||
server_running = false;
|
server_running = false;
|
||||||
delete connectionThread;
|
connectionThread.join();
|
||||||
connectionThread = NULL;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
THREAD_RETURN GeckoSockServer::GeckoConnectionWaiter(void*)
|
void GeckoSockServer::GeckoConnectionWaiter()
|
||||||
{
|
{
|
||||||
Common::SetCurrentThreadName("Gecko Connection Waiter");
|
Common::SetCurrentThreadName("Gecko Connection Waiter");
|
||||||
|
|
||||||
@ -70,7 +66,7 @@ THREAD_RETURN GeckoSockServer::GeckoConnectionWaiter(void*)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!server_running)
|
if (!server_running)
|
||||||
return 0;
|
return;
|
||||||
|
|
||||||
Core::DisplayMessage(
|
Core::DisplayMessage(
|
||||||
StringFromFormat("USBGecko: Listening on TCP port %u", server_port),
|
StringFromFormat("USBGecko: Listening on TCP port %u", server_port),
|
||||||
@ -90,7 +86,6 @@ THREAD_RETURN GeckoSockServer::GeckoConnectionWaiter(void*)
|
|||||||
SLEEP(1);
|
SLEEP(1);
|
||||||
}
|
}
|
||||||
server.Close();
|
server.Close();
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GeckoSockServer::GetAvailableSock(sf::SocketTCP &sock_to_fill)
|
bool GeckoSockServer::GetAvailableSock(sf::SocketTCP &sock_to_fill)
|
||||||
@ -101,15 +96,15 @@ bool GeckoSockServer::GetAvailableSock(sf::SocketTCP &sock_to_fill)
|
|||||||
if (waiting_socks.size())
|
if (waiting_socks.size())
|
||||||
{
|
{
|
||||||
sock_to_fill = waiting_socks.front();
|
sock_to_fill = waiting_socks.front();
|
||||||
if (clientThread)
|
if (clientThread.joinable())
|
||||||
{
|
{
|
||||||
client_running = false;
|
client_running = false;
|
||||||
delete clientThread;
|
clientThread.join();
|
||||||
clientThread = NULL;
|
|
||||||
recv_fifo = std::queue<u8>();
|
recv_fifo = std::queue<u8>();
|
||||||
send_fifo = std::queue<u8>();
|
send_fifo = std::queue<u8>();
|
||||||
}
|
}
|
||||||
clientThread = new Common::Thread(ClientThreadFunc, this);
|
clientThread = std::thread(ClientThreadFunc, this);
|
||||||
client_count++;
|
client_count++;
|
||||||
waiting_socks.pop();
|
waiting_socks.pop();
|
||||||
sock_filled = true;
|
sock_filled = true;
|
||||||
|
@ -33,7 +33,7 @@ public:
|
|||||||
// Client for this server object
|
// Client for this server object
|
||||||
sf::SocketTCP client;
|
sf::SocketTCP client;
|
||||||
void ClientThread();
|
void ClientThread();
|
||||||
Common::Thread *clientThread;
|
std::thread clientThread;
|
||||||
Common::CriticalSection transfer_lock;
|
Common::CriticalSection transfer_lock;
|
||||||
|
|
||||||
std::queue<u8> send_fifo;
|
std::queue<u8> send_fifo;
|
||||||
@ -44,11 +44,11 @@ private:
|
|||||||
volatile bool client_running;
|
volatile bool client_running;
|
||||||
|
|
||||||
// Only ever one server thread
|
// Only ever one server thread
|
||||||
static THREAD_RETURN GeckoConnectionWaiter(void*);
|
static void GeckoConnectionWaiter();
|
||||||
|
|
||||||
static u16 server_port;
|
static u16 server_port;
|
||||||
static volatile bool server_running;
|
static volatile bool server_running;
|
||||||
static Common::Thread *connectionThread;
|
static std::thread connectionThread;
|
||||||
static std::queue<sf::SocketTCP> waiting_socks;
|
static std::queue<sf::SocketTCP> waiting_socks;
|
||||||
static Common::CriticalSection connection_lock;
|
static Common::CriticalSection connection_lock;
|
||||||
};
|
};
|
||||||
|
@ -46,8 +46,7 @@ void CEXIMemoryCard::FlushCallback(u64 userdata, int cyclesLate)
|
|||||||
CEXIMemoryCard::CEXIMemoryCard(const std::string& _rName, const std::string& _rFilename, int _card_index) :
|
CEXIMemoryCard::CEXIMemoryCard(const std::string& _rName, const std::string& _rFilename, int _card_index) :
|
||||||
m_strFilename(_rFilename),
|
m_strFilename(_rFilename),
|
||||||
card_index(_card_index),
|
card_index(_card_index),
|
||||||
m_bDirty(false),
|
m_bDirty(false)
|
||||||
flushThread(NULL)
|
|
||||||
{
|
{
|
||||||
cards[_card_index] = this;
|
cards[_card_index] = this;
|
||||||
et_this_card = CoreTiming::RegisterEvent(_rName.c_str(), FlushCallback);
|
et_this_card = CoreTiming::RegisterEvent(_rName.c_str(), FlushCallback);
|
||||||
@ -103,9 +102,8 @@ CEXIMemoryCard::CEXIMemoryCard(const std::string& _rName, const std::string& _rF
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
THREAD_RETURN innerFlush(void *pArgs)
|
void innerFlush(flushStruct* data)
|
||||||
{
|
{
|
||||||
flushStruct *data = ((flushStruct *)pArgs);
|
|
||||||
FILE* pFile = NULL;
|
FILE* pFile = NULL;
|
||||||
pFile = fopen(data->filename.c_str(), "wb");
|
pFile = fopen(data->filename.c_str(), "wb");
|
||||||
|
|
||||||
@ -123,7 +121,7 @@ THREAD_RETURN innerFlush(void *pArgs)
|
|||||||
PanicAlertT("Could not write memory card file %s.\n\n"
|
PanicAlertT("Could not write memory card file %s.\n\n"
|
||||||
"Are you running Dolphin from a CD/DVD, or is the save file maybe write protected?", data->filename.c_str());
|
"Are you running Dolphin from a CD/DVD, or is the save file maybe write protected?", data->filename.c_str());
|
||||||
delete data;
|
delete data;
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fwrite(data->memcardContent, data->memcardSize, 1, pFile);
|
fwrite(data->memcardContent, data->memcardSize, 1, pFile);
|
||||||
@ -134,7 +132,7 @@ THREAD_RETURN innerFlush(void *pArgs)
|
|||||||
data->filename.c_str()).c_str(), 4000);
|
data->filename.c_str()).c_str(), 4000);
|
||||||
|
|
||||||
delete data;
|
delete data;
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flush memory card contents to disc
|
// Flush memory card contents to disc
|
||||||
@ -143,10 +141,9 @@ void CEXIMemoryCard::Flush(bool exiting)
|
|||||||
if(!m_bDirty)
|
if(!m_bDirty)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(flushThread)
|
if (flushThread.joinable())
|
||||||
{
|
{
|
||||||
delete flushThread;
|
flushThread.join();
|
||||||
flushThread = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!exiting)
|
if(!exiting)
|
||||||
@ -159,9 +156,9 @@ void CEXIMemoryCard::Flush(bool exiting)
|
|||||||
fs->memcardSize = memory_card_size;
|
fs->memcardSize = memory_card_size;
|
||||||
fs->bExiting = exiting;
|
fs->bExiting = exiting;
|
||||||
|
|
||||||
flushThread = new Common::Thread(innerFlush, fs);
|
flushThread = std::thread(innerFlush, fs);
|
||||||
if(exiting)
|
if (exiting)
|
||||||
flushThread->WaitForDeath();
|
flushThread.join();
|
||||||
|
|
||||||
m_bDirty = false;
|
m_bDirty = false;
|
||||||
}
|
}
|
||||||
@ -171,10 +168,10 @@ CEXIMemoryCard::~CEXIMemoryCard()
|
|||||||
Flush(true);
|
Flush(true);
|
||||||
delete[] memory_card_content;
|
delete[] memory_card_content;
|
||||||
memory_card_content = NULL;
|
memory_card_content = NULL;
|
||||||
if(flushThread)
|
|
||||||
|
if (flushThread.joinable())
|
||||||
{
|
{
|
||||||
delete flushThread;
|
flushThread.join();
|
||||||
flushThread = NULL;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,10 +183,9 @@ bool CEXIMemoryCard::IsPresent()
|
|||||||
void CEXIMemoryCard::SetCS(int cs)
|
void CEXIMemoryCard::SetCS(int cs)
|
||||||
{
|
{
|
||||||
// So that memory card won't be invalidated during flushing
|
// So that memory card won't be invalidated during flushing
|
||||||
if(flushThread)
|
if (flushThread.joinable())
|
||||||
{
|
{
|
||||||
delete flushThread;
|
flushThread.join();
|
||||||
flushThread = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cs) // not-selected to selected
|
if (cs) // not-selected to selected
|
||||||
|
@ -90,7 +90,7 @@ private:
|
|||||||
int memory_card_size; //! in bytes, must be power of 2.
|
int memory_card_size; //! in bytes, must be power of 2.
|
||||||
u8 *memory_card_content;
|
u8 *memory_card_content;
|
||||||
|
|
||||||
Common::Thread *flushThread;
|
std::thread flushThread;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void TransferByte(u8 &byte);
|
virtual void TransferByte(u8 &byte);
|
||||||
|
@ -22,14 +22,14 @@
|
|||||||
#include "Thread.h"
|
#include "Thread.h"
|
||||||
#include <queue>
|
#include <queue>
|
||||||
|
|
||||||
static Common::Thread *connectionThread = NULL;
|
static std::thread connectionThread;
|
||||||
static std::queue<sf::SocketTCP> waiting_socks;
|
static std::queue<sf::SocketTCP> waiting_socks;
|
||||||
static Common::CriticalSection cs_gba;
|
static Common::CriticalSection cs_gba;
|
||||||
namespace { volatile bool server_running; }
|
namespace { volatile bool server_running; }
|
||||||
|
|
||||||
// --- GameBoy Advance "Link Cable" ---
|
// --- GameBoy Advance "Link Cable" ---
|
||||||
|
|
||||||
THREAD_RETURN GBAConnectionWaiter(void*)
|
void GBAConnectionWaiter()
|
||||||
{
|
{
|
||||||
server_running = true;
|
server_running = true;
|
||||||
|
|
||||||
@ -38,7 +38,7 @@ THREAD_RETURN GBAConnectionWaiter(void*)
|
|||||||
sf::SocketTCP server;
|
sf::SocketTCP server;
|
||||||
// "dolphin gba"
|
// "dolphin gba"
|
||||||
if (!server.Listen(0xd6ba))
|
if (!server.Listen(0xd6ba))
|
||||||
return 0;
|
return;
|
||||||
|
|
||||||
server.SetBlocking(false);
|
server.SetBlocking(false);
|
||||||
|
|
||||||
@ -54,14 +54,14 @@ THREAD_RETURN GBAConnectionWaiter(void*)
|
|||||||
SLEEP(1);
|
SLEEP(1);
|
||||||
}
|
}
|
||||||
server.Close();
|
server.Close();
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GBAConnectionWaiter_Shutdown()
|
void GBAConnectionWaiter_Shutdown()
|
||||||
{
|
{
|
||||||
server_running = false;
|
server_running = false;
|
||||||
delete connectionThread;
|
if (connectionThread.joinable())
|
||||||
connectionThread = NULL;
|
connectionThread.join();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GetAvailableSock(sf::SocketTCP& sock_to_fill)
|
bool GetAvailableSock(sf::SocketTCP& sock_to_fill)
|
||||||
@ -82,8 +82,8 @@ bool GetAvailableSock(sf::SocketTCP& sock_to_fill)
|
|||||||
|
|
||||||
GBASockServer::GBASockServer()
|
GBASockServer::GBASockServer()
|
||||||
{
|
{
|
||||||
if (!connectionThread)
|
if (!connectionThread.joinable())
|
||||||
connectionThread = new Common::Thread(GBAConnectionWaiter, (void*)0);
|
connectionThread = std::thread(GBAConnectionWaiter);
|
||||||
}
|
}
|
||||||
|
|
||||||
GBASockServer::~GBASockServer()
|
GBASockServer::~GBASockServer()
|
||||||
|
@ -41,10 +41,10 @@ bool g_real_wiimotes_initialized = false;
|
|||||||
unsigned int g_wiimotes_found = 0;
|
unsigned int g_wiimotes_found = 0;
|
||||||
|
|
||||||
volatile bool g_run_wiimote_thread = false;
|
volatile bool g_run_wiimote_thread = false;
|
||||||
Common::Thread *g_wiimote_threads[MAX_WIIMOTES] = {};
|
std::thread g_wiimote_threads[MAX_WIIMOTES] = {};
|
||||||
Common::CriticalSection g_refresh_critsec;
|
Common::CriticalSection g_refresh_critsec;
|
||||||
|
|
||||||
THREAD_RETURN WiimoteThreadFunc(void* arg);
|
void WiimoteThreadFunc(Wiimote& arg);
|
||||||
void StartWiimoteThreads();
|
void StartWiimoteThreads();
|
||||||
void StopWiimoteThreads();
|
void StopWiimoteThreads();
|
||||||
|
|
||||||
@ -433,10 +433,10 @@ void Refresh()
|
|||||||
if (g_wiimotes[i] && (!(WIIMOTE_SRC_REAL & g_wiimote_sources[i]) ||
|
if (g_wiimotes[i] && (!(WIIMOTE_SRC_REAL & g_wiimote_sources[i]) ||
|
||||||
!g_wiimotes[i]->IsConnected()))
|
!g_wiimotes[i]->IsConnected()))
|
||||||
{
|
{
|
||||||
|
// TODO: this looks broken
|
||||||
delete g_wiimotes[i];
|
delete g_wiimotes[i];
|
||||||
g_wiimotes[i] = NULL;
|
g_wiimotes[i] = NULL;
|
||||||
delete g_wiimote_threads[i];
|
g_wiimote_threads[i].join();
|
||||||
g_wiimote_threads[i] = NULL;
|
|
||||||
--g_wiimotes_found;
|
--g_wiimotes_found;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -510,57 +510,51 @@ void StartWiimoteThreads()
|
|||||||
{
|
{
|
||||||
g_run_wiimote_thread = true;
|
g_run_wiimote_thread = true;
|
||||||
for (unsigned int i = 0; i < MAX_WIIMOTES; ++i)
|
for (unsigned int i = 0; i < MAX_WIIMOTES; ++i)
|
||||||
if (g_wiimotes[i] && !g_wiimote_threads[i])
|
if (g_wiimotes[i])
|
||||||
g_wiimote_threads[i] = new Common::Thread(WiimoteThreadFunc, g_wiimotes[i]);
|
g_wiimote_threads[i] = std::thread(WiimoteThreadFunc, *g_wiimotes[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void StopWiimoteThreads()
|
void StopWiimoteThreads()
|
||||||
{
|
{
|
||||||
g_run_wiimote_thread = false;
|
g_run_wiimote_thread = false;
|
||||||
for (unsigned int i = 0; i < MAX_WIIMOTES; ++i)
|
for (unsigned int i = 0; i < MAX_WIIMOTES; ++i)
|
||||||
if (g_wiimote_threads[i])
|
if (g_wiimote_threads[i].joinable())
|
||||||
{
|
g_wiimote_threads[i].join();
|
||||||
delete g_wiimote_threads[i];
|
|
||||||
g_wiimote_threads[i] = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
THREAD_RETURN WiimoteThreadFunc(void* arg)
|
void WiimoteThreadFunc(Wiimote& wiimote)
|
||||||
{
|
{
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Wiimote* const wiimote = (Wiimote*)arg;
|
|
||||||
|
|
||||||
char thname[] = "Wiimote # Thread";
|
char thname[] = "Wiimote # Thread";
|
||||||
thname[8] = (char)('1' + wiimote->index);
|
thname[8] = (char)('1' + wiimote.index);
|
||||||
Common::SetCurrentThreadName(thname);
|
Common::SetCurrentThreadName(thname);
|
||||||
|
|
||||||
// rumble briefly
|
// rumble briefly
|
||||||
wiimote->Rumble();
|
wiimote.Rumble();
|
||||||
|
|
||||||
Host_ConnectWiimote(wiimote->index, true);
|
Host_ConnectWiimote(wiimote.index, true);
|
||||||
|
|
||||||
// main loop
|
// main loop
|
||||||
while (g_run_wiimote_thread && wiimote->IsConnected())
|
while (g_run_wiimote_thread && wiimote.IsConnected())
|
||||||
{
|
{
|
||||||
// hopefully this is alright
|
// hopefully this is alright
|
||||||
while (wiimote->Write()) {}
|
while (wiimote.Write()) {}
|
||||||
|
|
||||||
#ifndef __APPLE__
|
#ifndef __APPLE__
|
||||||
// sleep if there was nothing to read
|
// sleep if there was nothing to read
|
||||||
if (false == wiimote->Read())
|
if (false == wiimote.Read())
|
||||||
#endif
|
#endif
|
||||||
Common::SleepCurrentThread(1);
|
Common::SleepCurrentThread(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
Host_ConnectWiimote(wiimote->index, false);
|
Host_ConnectWiimote(wiimote.index, false);
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
[pool release];
|
[pool release];
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}; // end of namespace
|
}; // end of namespace
|
||||||
|
@ -69,7 +69,7 @@ static u8 *undoLoad = NULL;
|
|||||||
|
|
||||||
static bool const bCompressed = true;
|
static bool const bCompressed = true;
|
||||||
|
|
||||||
static Common::Thread *saveThread = NULL;
|
static std::thread saveThread;
|
||||||
|
|
||||||
|
|
||||||
// Don't forget to increase this after doing changes on the savestate system
|
// Don't forget to increase this after doing changes on the savestate system
|
||||||
@ -159,9 +159,8 @@ void VerifyBufferStateCallback(u64 userdata, int cyclesLate)
|
|||||||
state_op_in_progress = false;
|
state_op_in_progress = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
THREAD_RETURN CompressAndDumpState(void *pArgs)
|
void CompressAndDumpState(saveStruct* saveArg)
|
||||||
{
|
{
|
||||||
saveStruct *saveArg = (saveStruct *)pArgs;
|
|
||||||
u8 *buffer = saveArg->buffer;
|
u8 *buffer = saveArg->buffer;
|
||||||
size_t sz = saveArg->size;
|
size_t sz = saveArg->size;
|
||||||
lzo_uint out_len = 0;
|
lzo_uint out_len = 0;
|
||||||
@ -185,7 +184,7 @@ THREAD_RETURN CompressAndDumpState(void *pArgs)
|
|||||||
{
|
{
|
||||||
Core::DisplayMessage("Could not save state", 2000);
|
Core::DisplayMessage("Could not save state", 2000);
|
||||||
delete[] buffer;
|
delete[] buffer;
|
||||||
return 0;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Setting up the header
|
// Setting up the header
|
||||||
@ -229,7 +228,6 @@ THREAD_RETURN CompressAndDumpState(void *pArgs)
|
|||||||
filename.c_str()).c_str(), 2000);
|
filename.c_str()).c_str(), 2000);
|
||||||
|
|
||||||
state_op_in_progress = false;
|
state_op_in_progress = false;
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SaveStateCallback(u64 userdata, int cyclesLate)
|
void SaveStateCallback(u64 userdata, int cyclesLate)
|
||||||
@ -263,7 +261,7 @@ void SaveStateCallback(u64 userdata, int cyclesLate)
|
|||||||
|
|
||||||
Core::DisplayMessage("Saving State...", 1000);
|
Core::DisplayMessage("Saving State...", 1000);
|
||||||
|
|
||||||
saveThread = new Common::Thread(CompressAndDumpState, saveData);
|
saveThread = std::thread(CompressAndDumpState, saveData);
|
||||||
|
|
||||||
// Resume the clock
|
// Resume the clock
|
||||||
PowerPC::Start();
|
PowerPC::Start();
|
||||||
@ -592,10 +590,9 @@ void State_VerifyBuffer(u8 **buffer)
|
|||||||
void State_Flush()
|
void State_Flush()
|
||||||
{
|
{
|
||||||
// If already saving state, wait for it to finish
|
// If already saving state, wait for it to finish
|
||||||
if (saveThread)
|
if (saveThread.joinable())
|
||||||
{
|
{
|
||||||
delete saveThread;
|
saveThread.join();
|
||||||
saveThread = NULL;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,10 +38,9 @@ extern CFrame* main_frame;
|
|||||||
|
|
||||||
DEFINE_EVENT_TYPE(wxEVT_THREAD)
|
DEFINE_EVENT_TYPE(wxEVT_THREAD)
|
||||||
|
|
||||||
THREAD_RETURN NetPlayThreadFunc(void* arg)
|
void NetPlayThreadFunc(NetPlay* np)
|
||||||
{
|
{
|
||||||
((NetPlay*)arg)->Entry();
|
np->Entry();
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// called from ---GUI--- thread
|
// called from ---GUI--- thread
|
||||||
|
@ -76,8 +76,6 @@ enum
|
|||||||
CON_ERR_VERSION_MISMATCH
|
CON_ERR_VERSION_MISMATCH
|
||||||
};
|
};
|
||||||
|
|
||||||
THREAD_RETURN NetPlayThreadFunc(void* arg);
|
|
||||||
|
|
||||||
// something like this should be in Common stuff
|
// something like this should be in Common stuff
|
||||||
class CritLocker
|
class CritLocker
|
||||||
{
|
{
|
||||||
@ -116,7 +114,6 @@ public:
|
|||||||
u8 GetPadNum(u8 numPAD);
|
u8 GetPadNum(u8 numPAD);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
//NetPlay(Common::ThreadFunc entry, void* arg) : m_thread(entry, arg) {}
|
|
||||||
//void GetBufferedPad(const u8 pad_nb, NetPad* const netvalues);
|
//void GetBufferedPad(const u8 pad_nb, NetPad* const netvalues);
|
||||||
void ClearBuffers();
|
void ClearBuffers();
|
||||||
void UpdateGUI();
|
void UpdateGUI();
|
||||||
@ -149,7 +146,7 @@ protected:
|
|||||||
|
|
||||||
NetPlayDiag* m_dialog;
|
NetPlayDiag* m_dialog;
|
||||||
sf::SocketTCP m_socket;
|
sf::SocketTCP m_socket;
|
||||||
Common::Thread* m_thread;
|
std::thread m_thread;
|
||||||
sf::Selector<sf::SocketTCP> m_selector;
|
sf::Selector<sf::SocketTCP> m_selector;
|
||||||
|
|
||||||
std::string m_selected_game;
|
std::string m_selected_game;
|
||||||
@ -166,6 +163,8 @@ private:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
void NetPlayThreadFunc(NetPlay* arg);
|
||||||
|
|
||||||
void NetPlay_Enable(NetPlay* const np);
|
void NetPlay_Enable(NetPlay* const np);
|
||||||
void NetPlay_Disable();
|
void NetPlay_Disable();
|
||||||
|
|
||||||
|
@ -7,8 +7,7 @@ NetPlayClient::~NetPlayClient()
|
|||||||
if (is_connected)
|
if (is_connected)
|
||||||
{
|
{
|
||||||
m_do_loop = false;
|
m_do_loop = false;
|
||||||
m_thread->WaitForDeath();
|
m_thread.join();
|
||||||
delete m_thread;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,7 +72,7 @@ NetPlayClient::NetPlayClient(const std::string& address, const u16 port, const s
|
|||||||
is_connected = true;
|
is_connected = true;
|
||||||
|
|
||||||
m_selector.Add(m_socket);
|
m_selector.Add(m_socket);
|
||||||
m_thread = new Common::Thread(NetPlayThreadFunc, this);
|
m_thread = std::thread(NetPlayThreadFunc, this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -7,8 +7,7 @@ NetPlayServer::~NetPlayServer()
|
|||||||
if (is_connected)
|
if (is_connected)
|
||||||
{
|
{
|
||||||
m_do_loop = false;
|
m_do_loop = false;
|
||||||
m_thread->WaitForDeath();
|
m_thread.join();
|
||||||
delete m_thread;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,7 +40,7 @@ NetPlayServer::NetPlayServer(const u16 port, const std::string& name, NetPlayDia
|
|||||||
is_connected = true;
|
is_connected = true;
|
||||||
|
|
||||||
m_selector.Add(m_socket);
|
m_selector.Add(m_socket);
|
||||||
m_thread = new Common::Thread(NetPlayThreadFunc, this);
|
m_thread = std::thread(NetPlayThreadFunc, this);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
is_connected = false;
|
is_connected = false;
|
||||||
|
@ -47,7 +47,7 @@
|
|||||||
|
|
||||||
struct UDPWiimote::_d
|
struct UDPWiimote::_d
|
||||||
{
|
{
|
||||||
Common::Thread * thread;
|
std::thread thread;
|
||||||
std::list<sock_t> sockfds;
|
std::list<sock_t> sockfds;
|
||||||
Common::CriticalSection termLock,mutex,nameMutex;
|
Common::CriticalSection termLock,mutex,nameMutex;
|
||||||
volatile bool exit;
|
volatile bool exit;
|
||||||
@ -56,15 +56,9 @@ struct UDPWiimote::_d
|
|||||||
|
|
||||||
int UDPWiimote::noinst=0;
|
int UDPWiimote::noinst=0;
|
||||||
|
|
||||||
void _UDPWiiThread(void* arg)
|
void UDPWiiThread(UDPWiimote* arg)
|
||||||
{
|
{
|
||||||
((UDPWiimote*)arg)->mainThread();
|
arg->mainThread();
|
||||||
}
|
|
||||||
|
|
||||||
THREAD_RETURN UDPWiiThread(void* arg)
|
|
||||||
{
|
|
||||||
_UDPWiiThread(arg);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UDPWiimote::UDPWiimote(const char *_port, const char * name, int _index) :
|
UDPWiimote::UDPWiimote(const char *_port, const char * name, int _index) :
|
||||||
@ -86,7 +80,6 @@ UDPWiimote::UDPWiimote(const char *_port, const char * name, int _index) :
|
|||||||
#endif
|
#endif
|
||||||
struct addrinfo hints, *servinfo, *p;
|
struct addrinfo hints, *servinfo, *p;
|
||||||
int rv;
|
int rv;
|
||||||
d->thread=NULL;
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
if (noinst==0)
|
if (noinst==0)
|
||||||
@ -142,7 +135,7 @@ UDPWiimote::UDPWiimote(const char *_port, const char * name, int _index) :
|
|||||||
initBroadcastIPv4();
|
initBroadcastIPv4();
|
||||||
initBroadcastIPv6();
|
initBroadcastIPv6();
|
||||||
d->termLock.Enter();
|
d->termLock.Enter();
|
||||||
d->thread = new Common::Thread(UDPWiiThread,this);
|
d->thread = std::thread(UDPWiiThread, this);
|
||||||
d->termLock.Leave();
|
d->termLock.Leave();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -226,8 +219,8 @@ void UDPWiimote::mainThread()
|
|||||||
|
|
||||||
UDPWiimote::~UDPWiimote()
|
UDPWiimote::~UDPWiimote()
|
||||||
{
|
{
|
||||||
d->exit=true;
|
d->exit = true;
|
||||||
d->thread->WaitForDeath();
|
d->thread.join();
|
||||||
d->termLock.Enter();
|
d->termLock.Enter();
|
||||||
d->termLock.Leave();
|
d->termLock.Leave();
|
||||||
for (std::list<sock_t>::iterator i=d->sockfds.begin(); i!=d->sockfds.end(); i++)
|
for (std::list<sock_t>::iterator i=d->sockfds.begin(); i!=d->sockfds.end(); i++)
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
class UDPWiimote
|
class UDPWiimote
|
||||||
{
|
{
|
||||||
|
friend void UDPWiiThread(UDPWiimote* arg);
|
||||||
public:
|
public:
|
||||||
UDPWiimote(const char * port, const char * name, int index);
|
UDPWiimote(const char * port, const char * name, int index);
|
||||||
virtual ~UDPWiimote();
|
virtual ~UDPWiimote();
|
||||||
@ -49,7 +50,6 @@ private:
|
|||||||
int index;
|
int index;
|
||||||
int int_port;
|
int int_port;
|
||||||
static int noinst;
|
static int noinst;
|
||||||
friend void _UDPWiiThread(void* arg);
|
|
||||||
void broadcastPresence();
|
void broadcastPresence();
|
||||||
void broadcastIPv4(const void * data, size_t size);
|
void broadcastIPv4(const void * data, size_t size);
|
||||||
void broadcastIPv6(const void * data, size_t size);
|
void broadcastIPv6(const void * data, size_t size);
|
||||||
|
@ -46,7 +46,7 @@ DSPConfigDialogLLE* m_ConfigFrame = NULL;
|
|||||||
|
|
||||||
PLUGIN_GLOBALS* globals = NULL;
|
PLUGIN_GLOBALS* globals = NULL;
|
||||||
DSPInitialize g_dspInitialize;
|
DSPInitialize g_dspInitialize;
|
||||||
Common::Thread *g_hDSPThread = NULL;
|
std::thread g_hDSPThread;
|
||||||
SoundStream *soundStream = NULL;
|
SoundStream *soundStream = NULL;
|
||||||
bool g_InitMixer = false;
|
bool g_InitMixer = false;
|
||||||
|
|
||||||
@ -211,7 +211,7 @@ void *DllDebugger(void *_hParent, bool Show)
|
|||||||
|
|
||||||
|
|
||||||
// Regular thread
|
// Regular thread
|
||||||
THREAD_RETURN dsp_thread(void* lpParameter)
|
void dsp_thread()
|
||||||
{
|
{
|
||||||
while (bIsRunning)
|
while (bIsRunning)
|
||||||
{
|
{
|
||||||
@ -226,7 +226,6 @@ THREAD_RETURN dsp_thread(void* lpParameter)
|
|||||||
}
|
}
|
||||||
// yield?
|
// yield?
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DSP_DebugBreak()
|
void DSP_DebugBreak()
|
||||||
@ -276,7 +275,7 @@ void Initialize(void *init)
|
|||||||
|
|
||||||
if (g_dspInitialize.bOnThread)
|
if (g_dspInitialize.bOnThread)
|
||||||
{
|
{
|
||||||
g_hDSPThread = new Common::Thread(dsp_thread, NULL);
|
g_hDSPThread = std::thread(dsp_thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(HAVE_WX) && HAVE_WX
|
#if defined(HAVE_WX) && HAVE_WX
|
||||||
@ -291,8 +290,7 @@ void DSP_StopSoundStream()
|
|||||||
bIsRunning = false;
|
bIsRunning = false;
|
||||||
if (g_dspInitialize.bOnThread)
|
if (g_dspInitialize.bOnThread)
|
||||||
{
|
{
|
||||||
delete g_hDSPThread;
|
g_hDSPThread.join();
|
||||||
g_hDSPThread = NULL;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,7 +108,7 @@ void UpdateFPSDisplay(const char *text)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if defined(HAVE_X11) && HAVE_X11
|
#if defined(HAVE_X11) && HAVE_X11
|
||||||
THREAD_RETURN XEventThread(void *pArg);
|
void XEventThread();
|
||||||
|
|
||||||
void CreateXWindow (void)
|
void CreateXWindow (void)
|
||||||
{
|
{
|
||||||
@ -137,7 +137,7 @@ void CreateXWindow (void)
|
|||||||
XMapRaised(GLWin.evdpy, GLWin.win);
|
XMapRaised(GLWin.evdpy, GLWin.win);
|
||||||
XSync(GLWin.evdpy, True);
|
XSync(GLWin.evdpy, True);
|
||||||
|
|
||||||
GLWin.xEventThread = new Common::Thread(XEventThread, NULL);
|
GLWin.xEventThread = std::thread(XEventThread);
|
||||||
}
|
}
|
||||||
|
|
||||||
void DestroyXWindow(void)
|
void DestroyXWindow(void)
|
||||||
@ -150,7 +150,7 @@ void DestroyXWindow(void)
|
|||||||
XFreeColormap(GLWin.evdpy, GLWin.attr.colormap);
|
XFreeColormap(GLWin.evdpy, GLWin.attr.colormap);
|
||||||
}
|
}
|
||||||
|
|
||||||
THREAD_RETURN XEventThread(void *pArg)
|
void XEventThread()
|
||||||
{
|
{
|
||||||
// Free look variables
|
// Free look variables
|
||||||
static bool mouseLookEnabled = false;
|
static bool mouseLookEnabled = false;
|
||||||
@ -305,7 +305,6 @@ THREAD_RETURN XEventThread(void *pArg)
|
|||||||
}
|
}
|
||||||
Common::SleepCurrentThread(20);
|
Common::SleepCurrentThread(20);
|
||||||
}
|
}
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -72,7 +72,7 @@ typedef struct {
|
|||||||
XVisualInfo *vi;
|
XVisualInfo *vi;
|
||||||
GLXContext ctx;
|
GLXContext ctx;
|
||||||
XSetWindowAttributes attr;
|
XSetWindowAttributes attr;
|
||||||
Common::Thread *xEventThread;
|
std::thread xEventThread;
|
||||||
int x, y;
|
int x, y;
|
||||||
unsigned int width, height;
|
unsigned int width, height;
|
||||||
#endif
|
#endif
|
||||||
|
@ -98,7 +98,7 @@ static bool s_bHaveCoverageMSAA = false;
|
|||||||
static u32 s_blendMode;
|
static u32 s_blendMode;
|
||||||
|
|
||||||
#if defined(HAVE_WX) && HAVE_WX
|
#if defined(HAVE_WX) && HAVE_WX
|
||||||
static Common::Thread *scrshotThread = 0;
|
static std::thread scrshotThread;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
@ -490,8 +490,8 @@ Renderer::~Renderer()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(HAVE_WX) && HAVE_WX
|
#if defined(HAVE_WX) && HAVE_WX
|
||||||
if (scrshotThread)
|
if (scrshotThread.joinable())
|
||||||
delete scrshotThread;
|
scrshotThread.join();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
delete g_framebuffer_manager;
|
delete g_framebuffer_manager;
|
||||||
@ -1496,10 +1496,8 @@ void Renderer::FlipImageData(u8 *data, int w, int h)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if defined(HAVE_WX) && HAVE_WX
|
#if defined(HAVE_WX) && HAVE_WX
|
||||||
THREAD_RETURN TakeScreenshot(void *pArgs)
|
void TakeScreenshot(ScrStrct* threadStruct)
|
||||||
{
|
{
|
||||||
ScrStrct *threadStruct = (ScrStrct *)pArgs;
|
|
||||||
|
|
||||||
// These will contain the final image size
|
// These will contain the final image size
|
||||||
float FloatW = (float)threadStruct->W;
|
float FloatW = (float)threadStruct->W;
|
||||||
float FloatH = (float)threadStruct->H;
|
float FloatH = (float)threadStruct->H;
|
||||||
@ -1538,8 +1536,6 @@ THREAD_RETURN TakeScreenshot(void *pArgs)
|
|||||||
OSD::AddMessage(StringFromFormat("Saved %i x %i %s", (int)FloatW, (int)FloatH,
|
OSD::AddMessage(StringFromFormat("Saved %i x %i %s", (int)FloatW, (int)FloatH,
|
||||||
threadStruct->filename.c_str()).c_str(), 2000);
|
threadStruct->filename.c_str()).c_str(), 2000);
|
||||||
delete threadStruct;
|
delete threadStruct;
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -1569,20 +1565,17 @@ bool Renderer::SaveScreenshot(const std::string &filename, const TargetRectangle
|
|||||||
// Create wxImage
|
// Create wxImage
|
||||||
wxImage *a = new wxImage(W, H, data);
|
wxImage *a = new wxImage(W, H, data);
|
||||||
|
|
||||||
if (scrshotThread)
|
if (scrshotThread.joinable())
|
||||||
{
|
scrshotThread.join();
|
||||||
delete scrshotThread;
|
|
||||||
scrshotThread = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
ScrStrct *threadStruct = new ScrStrct;
|
ScrStrct *threadStruct = new ScrStrct;
|
||||||
threadStruct->filename = filename;
|
threadStruct->filename = filename;
|
||||||
threadStruct->img = a;
|
threadStruct->img = a;
|
||||||
threadStruct->H = H; threadStruct->W = W;
|
threadStruct->H = H; threadStruct->W = W;
|
||||||
|
|
||||||
scrshotThread = new Common::Thread(TakeScreenshot, threadStruct);
|
scrshotThread = std::thread(TakeScreenshot, threadStruct);
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
scrshotThread->SetPriority(THREAD_PRIORITY_BELOW_NORMAL);
|
SetThreadPriority(scrshotThread.native_handle(), THREAD_PRIORITY_BELOW_NORMAL);
|
||||||
#endif
|
#endif
|
||||||
bool result = true;
|
bool result = true;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user