4#ifndef _Stroika_Foundation_Execution_Thread_h_
5#define _Stroika_Foundation_Execution_Thread_h_ 1
7#include "Stroika/Foundation/StroikaPreComp.h"
14#include "Stroika/Foundation/Common/Common.h"
16#include "Stroika/Foundation/Execution/Exceptions.h"
17#include "Stroika/Foundation/Execution/Signals.h"
37#ifndef qStroika_Foundation_Execution_Thread_SupportThreadStatistics
38#define qStroika_Foundation_Execution_Thread_SupportThreadStatistics qStroika_Foundation_Debug_AssertionsChecked
269#if qStroika_Platform_Windows
270 optional<bool> fThrowInterruptExceptionInsideUserAPC;
316 struct ConfigurationStatus : Configuration {
320 optional<const byte*> fStackBase;
325 optional<const byte*> fStackLimit;
330 optional<const byte*> fCurrentStackAt;
337 optional<size_t> GetStackUsed ()
const;
344 optional<size_t> GetStackAvailable ()
const;
375 Ptr (
const shared_ptr<Rep_>& rep);
380 nonvirtual
Ptr& operator= (
const Ptr& rhs);
381 nonvirtual
Ptr& operator= (
Ptr&& rhs)
noexcept;
389 nonvirtual
void reset () noexcept;
410#if defined(__cpp_lib_jthread)
414 nonvirtual stop_token GetStopToken ()
const;
444 nonvirtual
void Start ()
const;
447#if qStroika_Platform_Windows
459 nonvirtual
bool ThrowInterruptExceptionInsideUserAPC () const noexcept;
460 nonvirtual
bool ThrowInterruptExceptionInsideUserAPC (optional<
bool> throwInterruptExceptionInsideUserAPC);
490 nonvirtual
void Abort ()
const;
671#if qStroika_Platform_Windows
685 nonvirtual
void WaitForDoneWhilePumpingMessages (
Time::DurationSeconds timeout = Time::kInfinity)
const;
733 nonvirtual
bool IsDone () const;
775 nonvirtual
bool operator== (const
Ptr& rhs) const;
776 nonvirtual
bool operator== (nullptr_t) const;
781 nonvirtual strong_ordering operator<=> (const
Ptr& rhs) const;
782 nonvirtual strong_ordering operator<=> (nullptr_t) const;
788 nonvirtual explicit operator
bool () const;
791 shared_ptr<Rep_> fRep_;
793#if qCompilerAndStdLib_thread_local_static_inline_twice_Buggy
794 static weak_ptr<Rep_>& sCurrentThreadRep_BWA_ ()
796 static thread_local weak_ptr<Rep_> sCurrentThreadRep_;
797 return sCurrentThreadRep_;
800 static inline thread_local weak_ptr<Rep_> sCurrentThreadRep_;
804 friend Ptr New (
const function<
void ()>& fun2CallOnce,
const optional<Characters::String>& name,
const optional<Configuration>& configuration);
817 enum class AbortFlag {
821 using AbortFlag::eAbortBeforeWaiting;
822 using AbortFlag::eDirectlyWait;
851 class AbortException :
public Exception<> {
864 static const AbortException kThe;
866 inline const AbortException AbortException::kThe;
868 using InterruptException [[deprecated (
"Since Stroika v3.0d4 - use AbortException")]] = AbortException;
899 nonvirtual
unsigned int GetIndex (
const IDType& threadID,
bool* wasNew =
nullptr);
907 bool fInitialized_{
false};
909 map<IDType, unsigned int> fShownThreadIDs_;
990 Ptr New (
const function<
void ()>& fun2CallOnce,
const optional<Characters::String>& name,
const optional<Configuration>& configuration);
991 Ptr New (
const function<
void ()>& fun2CallOnce,
const Characters::String& name,
const optional<Configuration>& configuration = nullopt);
992 Ptr New (
const function<
void ()>& fun2CallOnce,
const optional<Configuration>& configuration = nullopt);
993 Ptr New (
const function<
void ()>& fun2CallOnce,
AutoStartFlag,
const optional<Characters::String>& name,
994 const optional<Configuration>& configuration);
996 const optional<Configuration>& configuration = nullopt);
997 Ptr New (
const function<
void ()>& fun2CallOnce,
AutoStartFlag,
const optional<Configuration>& configuration = nullopt);
1062 class AbortException;
1066#if qStroika_Foundation_Execution_Thread_SupportThreadStatistics
1081 Statistics GetStatistics ();
1084#if qStroika_Platform_POSIX
1090 SignalID SignalUsedForThreadInterrupt () noexcept;
1091 SignalID SignalUsedForThreadInterrupt (optional<SignalID> signalNumber);
1094 struct FormatThreadInfo {
1095 bool fIncludeLeadingZeros{
false};
1108 string FormatThreadID_A (
Thread::IDType threadID,
const FormatThreadInfo& formatInfo = {});
1112 IDType GetCurrentThreadID () noexcept;
1123#if defined(__cpp_lib_jthread)
1126 optional<stop_token> GetCurrentThreadStopToken ();
1160 dont_inline
void Yield ();
1171#include "Thread.inl"
#define Stroika_Define_Enum_Bounds(FIRST_ITEM, LAST_ITEM)
time_point< RealtimeClock, DurationSeconds > TimePointSeconds
TimePointSeconds is a simpler approach to chrono::time_point, which doesn't require using templates e...
chrono::duration< double > DurationSeconds
chrono::duration<double> - a time span (length of time) measured in seconds, but high precision.
#define Stroika_ATTRIBUTE_NO_UNIQUE_ADDRESS_VCFORCE
[[msvc::no_unique_address]] isn't always broken in MSVC. Annotate with this on things where its not b...
String is like std::u32string, except it is much easier to use, often much more space efficient,...
Exception<> is a replacement (subclass) for any std c++ exception class (e.g. the default 'std::excep...
CleanupPtr(const CleanupPtr &)=delete
in destructor, wait for the thread to terminate (optionally aborting it first - depending on CleahupP...
nonvirtual CleanupPtr & operator=(const Ptr &)
Thread::Ptr is a (unsynchronized) smart pointer referencing an internally synchronized std::thread ob...
friend void CheckForInterruption()
nonvirtual ConfigurationStatus GetConfigurationStatus() const
friend Ptr New(const function< void()> &fun2CallOnce, const optional< Characters::String > &name, const optional< Configuration > &configuration)
nonvirtual void SetThreadName(const Characters::String &threadName) const
nonvirtual void Join(Time::DurationSeconds timeout=Time::kInfinity) const
Wait for the pointed-to thread to be done. If the thread completed with an exception (other than thre...
nonvirtual void reset() noexcept
Clear the pointer this Thread smart pointer refers to. This does nothing to affect the state of the u...
nonvirtual void WaitForDoneUntil(Time::TimePointSeconds timeoutAt) const
nonvirtual void WaitForDone(Time::DurationSeconds timeout=Time::kInfinity) const
nonvirtual void Abort() const
Abort gracefully shuts down and terminates the given thread (using cooperative multitasking).
nonvirtual bool WaitForDoneUntilQuietly(Time::TimePointSeconds timeoutAt) const
nonvirtual void JoinUntil(Time::TimePointSeconds timeoutAt) const
Wait for the pointed-to thread to be done. If the thread completed with an exception (other than thre...
nonvirtual void Start() const
nonvirtual bool IsDone() const
nonvirtual void ThrowIfDoneWithException() const
nonvirtual function< void()> GetFunction() const
nonvirtual NativeHandleType GetNativeHandle() const noexcept
nonvirtual Characters::String ToString() const
nonvirtual IDType GetID() const
friend bool IsCurrentThreadInterruptible()
nonvirtual void AbortAndWaitForDone(Time::DurationSeconds timeout=Time::kInfinity) const
Abort () the thread, and then WaitForDone () (aka AbortAndWaitForDoneUntil (timeout + GetTickCount))
nonvirtual void AbortAndWaitForDoneUntil(Time::TimePointSeconds timeoutAt) const
Abort () the thread, and then WaitForDone ()
nonvirtual Characters::String GetThreadName() const
nonvirtual Status GetStatus() const noexcept
nonvirtual void SetThreadPriority(Priority priority=Priority::eNormal) const
Iterable<T> is a base class for containers which easily produce an Iterator<T> to traverse them.
Ptr New(const function< void()> &fun2CallOnce, const optional< Characters::String > &name, const optional< Configuration > &configuration)
void CheckForInterruption()
void AbortAndWaitForDoneUntil(const Traversal::Iterable< Ptr > &threads, Time::TimePointSeconds timeoutAt)
bool IsCurrentThreadInterruptible()
thread::native_handle_type NativeHandleType
void Start(const Traversal::Iterable< Ptr > &threads)
wstring FormatThreadID(Thread::IDType threadID, const FormatThreadInfo &formatInfo={})
void WaitForDone(const Traversal::Iterable< Ptr > &threads, Time::DurationSeconds timeout=Time::kInfinity)
dont_inline void Yield()
calls CheckForInterruption, and std::this_thread::yield ()
Configuration DefaultConfiguration() noexcept
void WaitForDoneUntil(const Traversal::Iterable< Ptr > &threads, Time::TimePointSeconds timeoutAt)
void Abort(const Traversal::Iterable< Ptr > &threads)
foreach Thread t: t.Abort ()
void AbortAndWaitForDone(const Traversal::Iterable< Ptr > &threads, Time::DurationSeconds timeout=Time::kInfinity)
shorthand for AbortAndWaitForDoneUntil (Time::GetTickCount () + timeout)
EXPERIMENTAL SUPPORT FOR THREAD STACK (and maybe other) settings.
optional< size_t > fStackGuard
optional< size_t > fStackSize