You're breathtaking!
This commit is contained in:
102
Source/Engine/Platform/Base/ThreadBase.cpp
Normal file
102
Source/Engine/Platform/Base/ThreadBase.cpp
Normal file
@@ -0,0 +1,102 @@
|
||||
// Copyright (c) 2012-2020 Wojciech Figat. All rights reserved.
|
||||
|
||||
#include "Engine/Platform/Thread.h"
|
||||
#include "Engine/Threading/IRunnable.h"
|
||||
#include "Engine/Threading/ThreadRegistry.h"
|
||||
#include "Engine/Core/Log.h"
|
||||
|
||||
Delegate<Thread*> ThreadBase::ThreadStarting;
|
||||
Delegate<Thread*, int32> ThreadBase::ThreadExiting;
|
||||
|
||||
ThreadBase::ThreadBase(IRunnable* runnable, const String& name, ThreadPriority priority)
|
||||
: _runnable(runnable)
|
||||
, _priority(priority)
|
||||
, _name(name)
|
||||
, _id(0)
|
||||
, _isRunning(false)
|
||||
, _callAfterWork(true)
|
||||
{
|
||||
ASSERT(_runnable);
|
||||
|
||||
#if BUILD_DEBUG
|
||||
// Cache name (in case if object gets deleted somewhere)
|
||||
_runnableName = _runnable->ToString();
|
||||
#endif
|
||||
}
|
||||
|
||||
void ThreadBase::SetPriority(ThreadPriority priority)
|
||||
{
|
||||
// Check if value won't change
|
||||
if (_priority != priority)
|
||||
{
|
||||
// Set new value
|
||||
_priority = priority;
|
||||
SetPriorityInternal(priority);
|
||||
}
|
||||
}
|
||||
|
||||
void ThreadBase::Kill(bool waitForJoin)
|
||||
{
|
||||
if (!_isRunning)
|
||||
return;
|
||||
ASSERT(GetID());
|
||||
const auto thread = static_cast<Thread*>(this);
|
||||
|
||||
// Stop runnable object
|
||||
if (_callAfterWork && _runnable)
|
||||
{
|
||||
_runnable->Stop();
|
||||
}
|
||||
|
||||
LOG(Info, "Killing thread \'{0}\' ID=0x{1:x}", _name, _id);
|
||||
|
||||
// Kill platform thread
|
||||
KillInternal(waitForJoin);
|
||||
ClearHandleInternal();
|
||||
|
||||
// End
|
||||
if (_callAfterWork)
|
||||
{
|
||||
_callAfterWork = false;
|
||||
_runnable->AfterWork(true);
|
||||
}
|
||||
_isRunning = false;
|
||||
ThreadRegistry::Remove(thread);
|
||||
}
|
||||
|
||||
int32 ThreadBase::Run()
|
||||
{
|
||||
// Setup
|
||||
ASSERT(_runnable);
|
||||
const auto thread = static_cast<Thread*>(this);
|
||||
_id = Platform::GetCurrentThreadID();
|
||||
ThreadRegistry::Add(thread);
|
||||
ThreadStarting(thread);
|
||||
int32 exitCode = 1;
|
||||
_isRunning = true;
|
||||
|
||||
LOG(Info, "Thread \'{0}\' ID=0x{1:x} started with priority {2}", _name, _id, ::ToString(GetPriority()));
|
||||
|
||||
if (_runnable->Init())
|
||||
{
|
||||
exitCode = _runnable->Run();
|
||||
|
||||
if (_callAfterWork) // Prevent from calling this after calling AfterWork since object may be deleted
|
||||
_runnable->Exit();
|
||||
}
|
||||
|
||||
LOG(Info, "Thread \'{0}\' ID=0x{1:x} exits with code {2}", _name, _id, exitCode);
|
||||
|
||||
// End
|
||||
if (_callAfterWork)
|
||||
{
|
||||
_callAfterWork = false;
|
||||
_runnable->AfterWork(false);
|
||||
}
|
||||
ClearHandleInternal();
|
||||
_isRunning = false;
|
||||
ThreadExiting(thread, exitCode);
|
||||
ThreadRegistry::Remove(thread);
|
||||
|
||||
return exitCode;
|
||||
}
|
||||
Reference in New Issue
Block a user