forked from Mirrorlandia_minetest/minetest
parent
0683bea283
commit
3fb1f45301
@ -73,7 +73,28 @@ Thread::Thread(const std::string &name) :
|
|||||||
|
|
||||||
Thread::~Thread()
|
Thread::~Thread()
|
||||||
{
|
{
|
||||||
kill();
|
// kill the thread if running
|
||||||
|
if (!m_running) {
|
||||||
|
wait();
|
||||||
|
} else {
|
||||||
|
|
||||||
|
m_running = false;
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
// See https://msdn.microsoft.com/en-us/library/hh920601.aspx#thread__native_handle_method
|
||||||
|
TerminateThread((HANDLE) m_thread_obj->native_handle(), 0);
|
||||||
|
CloseHandle((HANDLE) m_thread_obj->native_handle());
|
||||||
|
#else
|
||||||
|
// We need to pthread_kill instead on Android since NDKv5's pthread
|
||||||
|
// implementation is incomplete.
|
||||||
|
# ifdef __ANDROID__
|
||||||
|
pthread_kill(getThreadHandle(), SIGKILL);
|
||||||
|
# else
|
||||||
|
pthread_cancel(getThreadHandle());
|
||||||
|
# endif
|
||||||
|
wait();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
// Make sure start finished mutex is unlocked before it's destroyed
|
// Make sure start finished mutex is unlocked before it's destroyed
|
||||||
if (m_start_finished_mutex.try_lock())
|
if (m_start_finished_mutex.try_lock())
|
||||||
@ -138,37 +159,6 @@ bool Thread::wait()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Thread::kill()
|
|
||||||
{
|
|
||||||
if (!m_running) {
|
|
||||||
wait();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_running = false;
|
|
||||||
|
|
||||||
#if defined(_WIN32)
|
|
||||||
// See https://msdn.microsoft.com/en-us/library/hh920601.aspx#thread__native_handle_method
|
|
||||||
TerminateThread((HANDLE) m_thread_obj->native_handle(), 0);
|
|
||||||
CloseHandle((HANDLE) m_thread_obj->native_handle());
|
|
||||||
#else
|
|
||||||
// We need to pthread_kill instead on Android since NDKv5's pthread
|
|
||||||
// implementation is incomplete.
|
|
||||||
# ifdef __ANDROID__
|
|
||||||
pthread_kill(getThreadHandle(), SIGKILL);
|
|
||||||
# else
|
|
||||||
pthread_cancel(getThreadHandle());
|
|
||||||
# endif
|
|
||||||
wait();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
m_retval = nullptr;
|
|
||||||
m_joinable = false;
|
|
||||||
m_request_stop = false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Thread::getReturnValue(void **ret)
|
bool Thread::getReturnValue(void **ret)
|
||||||
{
|
{
|
||||||
|
@ -74,14 +74,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
bool stop();
|
bool stop();
|
||||||
|
|
||||||
/*
|
|
||||||
* Immediately terminates the thread.
|
|
||||||
* This should be used with extreme caution, as the thread will not have
|
|
||||||
* any opportunity to release resources it may be holding (such as memory
|
|
||||||
* or locks).
|
|
||||||
*/
|
|
||||||
bool kill();
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Waits for thread to finish.
|
* Waits for thread to finish.
|
||||||
* Note: This does not stop a thread, you have to do this on your own.
|
* Note: This does not stop a thread, you have to do this on your own.
|
||||||
|
@ -31,7 +31,6 @@ public:
|
|||||||
void runTests(IGameDef *gamedef);
|
void runTests(IGameDef *gamedef);
|
||||||
|
|
||||||
void testStartStopWait();
|
void testStartStopWait();
|
||||||
void testThreadKill();
|
|
||||||
void testAtomicSemaphoreThread();
|
void testAtomicSemaphoreThread();
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -40,7 +39,6 @@ static TestThreading g_test_instance;
|
|||||||
void TestThreading::runTests(IGameDef *gamedef)
|
void TestThreading::runTests(IGameDef *gamedef)
|
||||||
{
|
{
|
||||||
TEST(testStartStopWait);
|
TEST(testStartStopWait);
|
||||||
TEST(testThreadKill);
|
|
||||||
TEST(testAtomicSemaphoreThread);
|
TEST(testAtomicSemaphoreThread);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,29 +109,6 @@ void TestThreading::testStartStopWait()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void TestThreading::testThreadKill()
|
|
||||||
{
|
|
||||||
SimpleTestThread *thread = new SimpleTestThread(300);
|
|
||||||
|
|
||||||
UASSERT(thread->start() == true);
|
|
||||||
|
|
||||||
// kill()ing is quite violent, so let's make sure our victim is sleeping
|
|
||||||
// before we do this... so we don't corrupt the rest of the program's state
|
|
||||||
sleep_ms(100);
|
|
||||||
UASSERT(thread->kill() == true);
|
|
||||||
|
|
||||||
// The state of the thread object should be reset if all went well
|
|
||||||
UASSERT(thread->isRunning() == false);
|
|
||||||
UASSERT(thread->start() == true);
|
|
||||||
UASSERT(thread->stop() == true);
|
|
||||||
UASSERT(thread->wait() == true);
|
|
||||||
|
|
||||||
// kill() after already waiting should fail.
|
|
||||||
UASSERT(thread->kill() == false);
|
|
||||||
|
|
||||||
delete thread;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class AtomicTestThread : public Thread {
|
class AtomicTestThread : public Thread {
|
||||||
public:
|
public:
|
||||||
|
Loading…
Reference in New Issue
Block a user