[+] Added AuroraInterface IThreadVectors for thread creation
[+] ThreadInfo's constructor now accepts additional arguments for name and stack [*] Deprecate AbstractThreadVectors [+] note about detaching threads
This commit is contained in:
parent
81abb38316
commit
fe529f3dc4
@ -15,9 +15,15 @@ namespace Aurora::Threading::Threads
|
|||||||
User-provided interface-style callback structure of thread related events <br>
|
User-provided interface-style callback structure of thread related events <br>
|
||||||
DoRun/DoExit are called within the threads context
|
DoRun/DoExit are called within the threads context
|
||||||
*/
|
*/
|
||||||
|
/// @deprecated
|
||||||
struct AbstractThreadVectors
|
struct AbstractThreadVectors
|
||||||
{
|
{
|
||||||
std::function<void(IAuroraThread *)> DoRun;
|
AuConsumer<IAuroraThread *> DoRun;
|
||||||
std::function<void(IAuroraThread *)> DoExit;
|
AuConsumer<IAuroraThread *> DoExit;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
AUKN_INTERFACE(IThreadVectors,
|
||||||
|
AUI_METHOD(void, OnEntry, (IAuroraThread *, thread)),
|
||||||
|
AUI_METHOD(void, OnExit, (IAuroraThread *, thread))
|
||||||
|
);
|
||||||
}
|
}
|
@ -15,6 +15,25 @@ namespace Aurora::Threading::Threads
|
|||||||
class IAuroraThread
|
class IAuroraThread
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
// TODO: consider detach support.
|
||||||
|
// It's actually really comfy that resetting/destroying the thread forces you to sync to termination
|
||||||
|
// The common/forced semantic:
|
||||||
|
// worker->SendExitSignal(); // sets the exiting flag
|
||||||
|
// DestoryThread(worker); // in the dtor, a watchdog is triggered over the shutdown of the thread
|
||||||
|
//
|
||||||
|
// WorkerMain()
|
||||||
|
// while (!this->Exiting()) {}
|
||||||
|
//
|
||||||
|
// It's Similar to Java
|
||||||
|
// -> think while (Thread.currentThread().isAlive()) { doWork() }
|
||||||
|
// -> plus you own the thread and its' execution
|
||||||
|
//
|
||||||
|
// One could always use AsWaitable() to get an event object that is triggered once the thread shuts down
|
||||||
|
// It's not like there isn't a traditional IWaitable interface support backing on thread termination
|
||||||
|
// The problem is, if the aurora runtime transfers ownership of an IAuroraThread to you, you have to leak it
|
||||||
|
// or you have to be forced to use the very comfy dtor mechanic. We need a detach function to overload this
|
||||||
|
// release is always terminate assumption.
|
||||||
|
|
||||||
virtual bool Run() = 0;
|
virtual bool Run() = 0;
|
||||||
virtual void Exit() = 0;
|
virtual void Exit() = 0;
|
||||||
virtual bool Exiting() = 0;
|
virtual bool Exiting() = 0;
|
||||||
|
@ -11,11 +11,26 @@ namespace Aurora::Threading::Threads
|
|||||||
{
|
{
|
||||||
struct ThreadInfo
|
struct ThreadInfo
|
||||||
{
|
{
|
||||||
const AbstractThreadVectors &vectors;
|
/// @deprecated
|
||||||
|
AbstractThreadVectors vectors;
|
||||||
|
AuSPtr<IThreadVectors> callbacks;
|
||||||
|
|
||||||
|
/// @deprecated
|
||||||
ThreadInfo(const AbstractThreadVectors &vectors) : vectors(vectors)
|
ThreadInfo(const AbstractThreadVectors &vectors) : vectors(vectors)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
|
ThreadInfo(const AuSPtr<IThreadVectors> &callbacks) : callbacks(callbacks)
|
||||||
|
{}
|
||||||
|
|
||||||
|
ThreadInfo(const AuSPtr<IThreadVectors> &callbacks, const AuString &name) : callbacks(callbacks), name(name)
|
||||||
|
{}
|
||||||
|
|
||||||
|
ThreadInfo(const AuSPtr<IThreadVectors> &callbacks, const AuString &name, AuUInt32 stackSize) : callbacks(callbacks), name(name), stackSize(stackSize)
|
||||||
|
{}
|
||||||
|
|
||||||
|
ThreadInfo(const AuSPtr<IThreadVectors> &callbacks, AuUInt32 stackSize) : callbacks(callbacks), name(name), stackSize(stackSize)
|
||||||
|
{}
|
||||||
|
|
||||||
AuOptional<AuUInt32> stackSize;
|
AuOptional<AuUInt32> stackSize;
|
||||||
AuOptional<AuString> name;
|
AuOptional<AuString> name;
|
||||||
};
|
};
|
||||||
|
@ -30,9 +30,8 @@ namespace Aurora::Threading::Threads
|
|||||||
static AbstractThreadVectors gDummyVectors {};
|
static AbstractThreadVectors gDummyVectors {};
|
||||||
static ThreadInfo gDummyThreadInfo(gDummyVectors);
|
static ThreadInfo gDummyThreadInfo(gDummyVectors);
|
||||||
|
|
||||||
OSThread::OSThread(const ThreadInfo &info) : info_(vecs)
|
OSThread::OSThread(const ThreadInfo &info) : info_(info)
|
||||||
{
|
{
|
||||||
vecs = info.vectors;
|
|
||||||
info_.stackSize = info.stackSize;
|
info_.stackSize = info.stackSize;
|
||||||
info_.name = info.name;
|
info_.name = info.name;
|
||||||
name_ = info.name.value_or("Aurora Thread");
|
name_ = info.name.value_or("Aurora Thread");
|
||||||
@ -121,10 +120,15 @@ namespace Aurora::Threading::Threads
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
// this functional backends are being deprecated
|
||||||
if (info_.vectors.DoRun)
|
if (info_.vectors.DoRun)
|
||||||
{
|
{
|
||||||
info_.vectors.DoRun(this);
|
info_.vectors.DoRun(this);
|
||||||
}
|
}
|
||||||
|
else if (info_.callbacks)
|
||||||
|
{
|
||||||
|
info_.callbacks->OnEntry(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
@ -553,23 +557,27 @@ namespace Aurora::Threading::Threads
|
|||||||
|
|
||||||
HookOnExit();
|
HookOnExit();
|
||||||
|
|
||||||
// dispatch kill callback
|
try
|
||||||
if (info_.vectors.DoExit)
|
|
||||||
{
|
{
|
||||||
try
|
// dispatch kill callback
|
||||||
|
if (info_.vectors.DoExit)
|
||||||
{
|
{
|
||||||
info_.vectors.DoExit(this);
|
info_.vectors.DoExit(this);
|
||||||
}
|
}
|
||||||
catch (...)
|
else if (info_.callbacks)
|
||||||
{
|
{
|
||||||
Debug::PrintError();
|
info_.callbacks->OnExit(this);
|
||||||
LogWarn("Couldn't deinitialize thread");
|
|
||||||
LogWarn("The smart thing to do at this point would be to panic");
|
|
||||||
LogWarn("...but we could continue");
|
|
||||||
LogWarn("Carrying on despite the potential for data integrity loss and memory leaks");
|
|
||||||
Telemetry::Mayday();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
Debug::PrintError();
|
||||||
|
LogWarn("Couldn't deinitialize thread");
|
||||||
|
LogWarn("The smart thing to do at this point would be to panic");
|
||||||
|
LogWarn("...but we could continue");
|
||||||
|
LogWarn("Carrying on despite the potential for data integrity loss and memory leaks");
|
||||||
|
Telemetry::Mayday();
|
||||||
|
}
|
||||||
|
|
||||||
HookReleaseThreadResources();
|
HookReleaseThreadResources();
|
||||||
|
|
||||||
|
@ -59,7 +59,6 @@ namespace Aurora::Threading::Threads
|
|||||||
Primitives::SpinLock tlsLock_;
|
Primitives::SpinLock tlsLock_;
|
||||||
AuSPtr<TLSView> tls_;
|
AuSPtr<TLSView> tls_;
|
||||||
AuString name_;
|
AuString name_;
|
||||||
AbstractThreadVectors vecs;
|
|
||||||
ThreadInfo info_;
|
ThreadInfo info_;
|
||||||
AuUInt32 affinityProcessMask_ = 0xFFFFFFFF;
|
AuUInt32 affinityProcessMask_ = 0xFFFFFFFF;
|
||||||
EThreadPrio prio_ = EThreadPrio::ePrioNormal;
|
EThreadPrio prio_ = EThreadPrio::ePrioNormal;
|
||||||
|
@ -87,7 +87,10 @@ namespace Aurora::Threading::Threads
|
|||||||
void OsThreadShutdown(AuUInt64 threadId)
|
void OsThreadShutdown(AuUInt64 threadId)
|
||||||
{
|
{
|
||||||
SysAssertDbg(tlsOsFallbackThread.threadId == threadId);
|
SysAssertDbg(tlsOsFallbackThread.threadId == threadId);
|
||||||
SafeDelete<OSThread *>(tlsOsFallbackThread.handle);
|
if (tlsOsFallbackThread.handle)
|
||||||
|
{
|
||||||
|
SafeDelete<OSThread *>(tlsOsFallbackThread.handle);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AUKN_SYM IAuroraThread *GetThread()
|
AUKN_SYM IAuroraThread *GetThread()
|
||||||
|
@ -13,6 +13,7 @@ namespace Aurora::Threading::Threads
|
|||||||
{
|
{
|
||||||
AUKN_SYM IAuroraThread *ThreadNew(const ThreadInfo &info)
|
AUKN_SYM IAuroraThread *ThreadNew(const ThreadInfo &info)
|
||||||
{
|
{
|
||||||
|
if (!info.callbacks && !(info.vectors.DoRun)) return {};
|
||||||
return _new OSThread(info);
|
return _new OSThread(info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user