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
246#if qStroika_Foundation_Common_Platform_Windows
247 optional<bool> fThrowInterruptExceptionInsideUserAPC;
293 struct ConfigurationStatus : Configuration {
297 optional<const byte*> fStackBase;
302 optional<const byte*> fStackLimit;
307 optional<const byte*> fCurrentStackAt;
314 optional<size_t> GetStackUsed ()
const;
321 optional<size_t> GetStackAvailable ()
const;
352 Ptr (
const shared_ptr<Rep_>& rep);
357 nonvirtual
Ptr& operator= (
const Ptr& rhs);
358 nonvirtual
Ptr& operator= (
Ptr&& rhs)
noexcept;
366 nonvirtual
void reset () noexcept;
387#if __cpp_lib_jthread >= 201911
391 nonvirtual stop_token GetStopToken ()
const;
421 nonvirtual
void Start ()
const;
424#if qStroika_Foundation_Common_Platform_Windows
436 nonvirtual
bool ThrowInterruptExceptionInsideUserAPC () const noexcept;
437 nonvirtual
bool ThrowInterruptExceptionInsideUserAPC (optional<
bool> throwInterruptExceptionInsideUserAPC);
467 nonvirtual
void Abort ()
const;
639#if qStroika_Foundation_Common_Platform_Windows
653 nonvirtual
void WaitForDoneWhilePumpingMessages (
Time::DurationSeconds timeout = Time::kInfinity)
const;
701 nonvirtual
bool IsDone () const;
743 nonvirtual
bool operator== (const
Ptr& rhs) const;
744 nonvirtual
bool operator== (nullptr_t) const;
749 nonvirtual strong_ordering operator<=> (const
Ptr& rhs) const;
750 nonvirtual strong_ordering operator<=> (nullptr_t) const;
756 nonvirtual explicit operator
bool () const;
759 shared_ptr<Rep_> fRep_;
760 [[no_unique_address]] Debug::AssertExternallySynchronizedMutex fThisAssertExternallySynchronized_;
761#if qCompilerAndStdLib_thread_local_static_inline_twice_Buggy
762 static weak_ptr<Rep_>& sCurrentThreadRep_BWA_ ()
764 static thread_local weak_ptr<Rep_> sCurrentThreadRep_;
765 return sCurrentThreadRep_;
768 static inline thread_local weak_ptr<Rep_> sCurrentThreadRep_;
772 friend Ptr New (
const function<
void ()>& fun2CallOnce,
const optional<Characters::String>& name,
const optional<Configuration>& configuration);
785 enum class AbortFlag {
789 using AbortFlag::eAbortBeforeWaiting;
790 using AbortFlag::eDirectlyWait;
819 class AbortException :
public Exception<> {
832 static const AbortException kThe;
834 inline const AbortException AbortException::kThe;
836 using InterruptException [[deprecated (
"Since Stroika v3.0d4 - use AbortException")]] = AbortException;
867 nonvirtual
unsigned int GetIndex (
const IDType& threadID,
bool* wasNew =
nullptr);
875 bool fInitialized_{
false};
877 map<IDType, unsigned int> fShownThreadIDs_;
948 Ptr New (
const function<
void ()>& fun2CallOnce,
const optional<Characters::String>& name,
const optional<Configuration>& configuration);
949 Ptr New (
const function<
void ()>& fun2CallOnce,
const Characters::String& name,
const optional<Configuration>& configuration = nullopt);
950 Ptr New (
const function<
void ()>& fun2CallOnce,
const optional<Configuration>& configuration = nullopt);
951 Ptr New (
const function<
void ()>& fun2CallOnce,
AutoStartFlag,
const optional<Characters::String>& name,
952 const optional<Configuration>& configuration);
954 const optional<Configuration>& configuration = nullopt);
955 Ptr New (
const function<
void ()>& fun2CallOnce,
AutoStartFlag,
const optional<Configuration>& configuration = nullopt);
1020 class AbortException;
1024#if qStroika_Foundation_Execution_Thread_SupportThreadStatistics
1039 Statistics GetStatistics ();
1042#if qStroika_Foundation_Common_Platform_POSIX
1048 SignalID SignalUsedForThreadInterrupt () noexcept;
1049 SignalID SignalUsedForThreadInterrupt (optional<SignalID> signalNumber);
1052 struct FormatThreadInfo {
1053 bool fIncludeLeadingZeros{
false};
1066 string FormatThreadID_A (
Thread::IDType threadID,
const FormatThreadInfo& formatInfo = {});
1070 IDType GetCurrentThreadID () noexcept;
1081#if __cpp_lib_jthread >= 201911
1084 optional<stop_token> GetCurrentThreadStopToken ();
1118 dont_inline
void Yield ();
1129#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.
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 () - but if doesn't finish fast enough, send extra aborts (...
nonvirtual void AbortAndWaitForDoneUntil(Time::TimePointSeconds timeoutAt) const
Abort () the thread, and then WaitForDone () - but if doesn't finish fast enough, send extra aborts.
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