/*** Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: OSThread.hpp Date: 2021-6-12 Author: Reece ***/ #pragma once namespace Aurora::Threading::Threads { class OSThread : public IAuroraThread { public: OSThread(); OSThread(const ThreadInfo &info); OSThread(AuUInt64); ~OSThread(); bool Run() override; void Exit() override; bool Exiting() override; void SendExitSignal() override; void SetPrio(EThreadPrio prio) override; void SetAffinity(AuUInt32 mask) override; void SetName(const AuString &name) override; EThreadPrio GetPrio() override; AuUInt32 GetMask() override; AuString GetName() override; AuSPtr GetTlsView() override; void ExecuteInDeadThread(std::function callback) override; AuSPtr AsWaitable() override; void AddLastHopeTlsHook(const AuSPtr &feature) override; void _ThreadEP(); protected: bool Exit(bool willReturnToOS); bool ExecuteNewOSContext(std::function task); void UpdatePrio(EThreadPrio prio); void UpdateAffinity(AuUInt32 mask); void UpdateName(); void Attach(); void Deattach(); bool InternalKill(bool locked); void TeminateOSContext(bool calledFromThis); void FreeOSContext(); void HookReleaseThreadResources(); void HookOnExit(); private: Primitives::SpinLock tlsLock_; AuSPtr tls_; AuString name_; AbstractThreadVectors vecs; ThreadInfo info_; AuUInt32 affinityProcessMask_ = 0xFFFFFFFF; EThreadPrio prio_ = EThreadPrio::ePrioNormal; bool exiting_{}; bool contextUsed_{}; // can this thread instance execute code again? Primitives::EventShared_t terminated_; Primitives::CriticalSectionUnique_t exitOnlyOnce_; AuList> threadFeatures_; std::function task_; #if defined(AURORA_IS_MODERNNT_DERIVED) HANDLE handle_ = INVALID_HANDLE_VALUE; #elif defined(AURORA_HAS_PTHREADS) pthread_t handle_; #endif AuUInt64 unixThreadId_ = 0; }; }