Stroika Library 3.0d16
 
Loading...
Searching...
No Matches
Stroika::Foundation::Execution Namespace Reference

Namespaces

namespace  Thread
 Thread is a namespace for Stroika thread code,.
 
namespace  WaitForIOReady_Support
 

Classes

class  AbortableMutex
 
class  Activity
 
class  BlockingQueue
 
class  CommandLine
 
struct  ConditionVariable
 
class  DeclareActivity
 
class  DLLLoader
 
class  Exception
 Exception<> is a replacement (subclass) for any std c++ exception class (e.g. the default 'std::exception'), which adds UNICODE String support. More...
 
class  ExceptionStringHelper
 
class  FeatureNotSupportedException
 
class  Function
 
class  IntervalTimer
 Manage interval timers - like the javascript setIntervalTimer API. More...
 
class  InvalidCommandLineArgument
 
class  LazyEvalActivity
 
class  LazyInitialized
 value-object, where the value construction is delayed until first needed (can be handy to avoid c++ include/initializer deadly embrace) More...
 
class  Logger
 A simple/portable wrapper on syslog/log4j/WindowsEventlog, with features like throttling, de-duping, varargs, etc. More...
 
struct  ModuleGetterSetter
 Helper to define synchronized, lazy constructed, module initialization (intended to work with DataExchange::OptionFile) More...
 
class  NestedException
 NestedException contains a new higher level error message (typically based on argument basedOnException) and preserves the original exception (which you can use to get its message, with Characters::ToString (fBasedOnException) More...
 
struct  NullMutex
 
class  OperationNotSupportedException
 
class  PIDLoop
 
class  ProcessRunner
 Run the given command, and optionally support stdin/stdout/stderr as streams (either sync with Run, RunInBackground) More...
 
class  ProgressMonitor
 
class  RuntimeErrorException
 
class  SharedStaticData
 
class  SignalHandler
 
class  SignalHandlerRegistry
 
class  SilentException
 
class  SpinLock
 
class  Synchronized
 Wrap any object with Synchronized<> and it can be used similarly to the base type, but safely in a thread safe manner, from multiple threads. This is similar to std::atomic. More...
 
struct  Synchronized_Traits
 
class  SystemErrorException
 
class  ThreadPool
 
class  TimedLockGuard
 
class  TimeOutException
 
class  UpdatableWaitForIOReady
 Simple wrapper on WaitForIOReady (POSIX select/poll/etc API) - except it allows for the list if polled descriptors to be updated dynamically from any thread, and have that automatically wakeup any waiters to restart waiting. More...
 
class  UserCanceledException
 
class  WaitableEvent
 
class  WaitForIOReady
 
struct  WhenTimeExceeded
 

Typedefs

using errno_t = int
 
using pid_t = int
 TODO - maybe move this to configuraiotn module???
 
template<typename T >
using QuickSynchronized = conditional_t< kSpinLock_IsFasterThan_mutex, Synchronized< T, Synchronized_Traits< SpinLock > >, Synchronized< T, Synchronized_Traits< mutex > > >
 
template<typename T >
using TimedSynchronized = Synchronized< T, Synchronized_Traits< recursive_timed_mutex > >
 
template<typename T >
using RWSynchronized = Synchronized< T, Synchronized_Traits< shared_timed_mutex > >
 

Enumerations

enum class  SequencePolicy { eSeq , ePar , eParUnseq , eUnseq , Stroika_Define_Enum_Bounds }
 equivalent which of 4 types being used std::execution::sequenced_policy, parallel_policy, etc... More...
 
enum class  InternallySynchronized
 

Functions

void ThrowSystemErrNo (int sysErr)
 treats sysErr as a platform-defined error number, and throws a SystemErrorException (subclass of @std::system_error) exception with it.
 
Containers::Stack< Activity<> > CaptureCurrentActivities ()
 Returns a copyable preservable version of the current activities stack.
 
template<invocable<>... I>
void RunAll (I... functions)
 Run all the argument functions (logically/potentially) in parallel, and wait until they all complete.
 
void ThrowPOSIXErrNo (errno_t errNo=errno)
 treats errNo as a POSIX errno value, and throws a SystemError (subclass of @std::system_error) exception with it.
 
template<typename INT_TYPE >
INT_TYPE ThrowPOSIXErrNoIfNegative (INT_TYPE returnCode)
 
template<typename CALL >
auto Handle_ErrNoResultInterruption (CALL call) -> decltype(call())
 Handle UNIX EINTR system call behavior - fairly transparently - just effectively removes them from the set of errors that can be returned.
 
void ThrowPOSIXErrNoIfNull (void *returnValue)
 
optional< error_code > GetAssociatedErrorCode (const exception_ptr &e) noexcept
 
template<typename F >
auto TranslateExceptionToOptional (F &&f) -> optional< remove_cvref_t< invoke_result_t< F > > >
 
template<Common::INoThrowInvocable FUNCTION>
auto Finally (FUNCTION &&f) -> Private_::FinallySentry< FUNCTION >
 
void DefaultLoggingFatalErrorHandler (const Characters::SDKChar *msg) noexcept
 
void DefaultLoggingCrashSignalHandler (Execution::SignalID signal) noexcept
 
filesystem::path GetEXEDir ()
 
filesystem::path GetEXEPath ()
 
filesystem::path GetEXEPath (pid_t processID)
 
optional< filesystem::path > FindExecutableInPath (const filesystem::path &fn)
 If fn refers to an executable - return it (using kPATH, and kPathEXT as appropriate)
 
template<>
void ThrowIfNull (const Private_::ConstVoidStar &p, const HRESULT &hr)
 Template specialization for ThrowIfNull (), for thing being thrown HRESULT - really throw HRESULTErrorException.
 
template<>
void ThrowIfNull (const Private_::ConstVoidStar &p, const HRESULT &hr)
 Template specialization for ThrowIfNull (), for thing being thrown HRESULT - really throw HRESULTErrorException.
 
bool IsProcessRunning (pid_t pid)
 
pid_t DetachedProcessRunner (const filesystem::path &executable, const Containers::Sequence< String > &args)
 DEPRECATED.
 
template<typename T >
Streams::InputStream::Ptr< T > MakeInputStreamWithProgress (const Streams::InputStream::Ptr< T > &in, ProgressMonitor::Updater progress)
 
errno_t SendSignal (thread::native_handle_type target, SignalID signal)
 
void Sleep (Time::Duration seconds2Wait)
 
void SleepUntil (Time::TimePointSeconds untilTickCount)
 
void ThrowTimeOutException ()
 Execution::Throw (Execution::TimeOutException::kThe); but can be more easily forward-declared, so no include deadly embrace.
 
template<typename T >
void Throw (T &&e2Throw)
 identical to builtin C++ 'throw' except that it does helpful, type dependent DbgTrace() messages first
 
void ReThrow ()
 
template<equality_comparable_with< nullptr_t > T, typename E >
void ThrowIfNull (const T &p, const E &e)
 
template<typename EXCEPTION >
void ThrowTimeoutExceptionAfter (Time::TimePointSeconds afterTickCount, EXCEPTION &&exception2Throw)
 Throw TimeOutException if the @Time::GetTickCount () is >= the given value.
 
template<typename TIMED_MUTEX , typename EXCEPTION >
void TryLockUntil (TIMED_MUTEX &m, Time::TimePointSeconds afterTickCount, EXCEPTION &&exception2Throw)
 
template<typename EXCEPTION >
void ThrowIfTimeout (cv_status conditionVariableStatus, EXCEPTION &&exception2Throw)
 
template<typename TIMED_MUTEX , typename EXCEPTION >
unique_lock< TIMED_MUTEX > UniqueLock (TIMED_MUTEX &m, const chrono::duration< double > &d, EXCEPTION &&exception2Throw)
 

Variables

const LazyInitialized< Containers::Sequence< filesystem::path > > kPath
 
const LazyInitialized< Containers::Mapping< Characters::SDKString, Characters::SDKString > > kRawEnvironment
 convert getenv() to a Mapping of SDKString (in case some issue with charactor set conversion)
 
const LazyInitialized< Containers::Mapping< Characters::String, Characters::String > > kEnvironment
 convert getenv() to a Mapping of Strings for easier access
 
constexpr bool kSpinLock_IsFasterThan_mutex = true
 

Detailed Description

Note
Code-Status: Beta
Design Note (essentially) All exceptions thrown by Stroika (except where needed by quirks of underlying library integrated with) inherit from std::exception, or are Stroika::Foundation::Execution::SilentException.

This means that any code which wishes to report an exception can catch these two types, and use the 'what()' method to report the text of the exception message.

Sadly, there is no documentation (I'm aware of) or specification of the character set/code page reported back by the what () on an exception. It tends to be ascii. Stroika guarantees that all exceptions it throws will use the current SDK characters (

See also
SDKString). But - its best to use Characters::ToString () on the caught exception, since this uses ExceptionStringHelper to properly handle characters the SDK character set might not allow representing some unicode characters.

TODO:

Note
Code-Status: Alpha
Note
Code-Status: Beta

TODO:

So data pusher/buffer loop does select on external streams to see if data available.

This implies I must also be able to do the moral equivalent of selects on my BinaryInput/Output streams? Maybe, unless I do all the buffering... But at least for the stdin stream - I need to be able to check if/when there is new data available!!! TRICKY

And related - what if we create a runner, and then destroy the object? How to assure runner fully destroyed? Blocking/waiting or error or detached state?

Design Goals: o Be able to run simple processes and capture output with little overhead, and very easy to do (like perl backticks).

o Be able to support pipes between processes (either within the shell, or between Stroika threads)

o Support large data and blocking issues properly - automating avoidance of pipe full bugs which block processes

o Efficient/Low performance overhead

o For POSIX - simple to cleanly cleanup open sockets/resources (not needed on windows)

o Separate threading implementation from API, so easy to externally specify the thread stuff runs on (e.g. so you can use thread pools to run the processes).

o Work with stroika streams so its easy to have user-defined producers and consumers, and easy to hook together TextStreams (wrappers) - for format conversion/piping.

Design Overview o

TODO:

Note
Code-Status: Alpha
@todo   BETTER INTEGRATE STROIKA THREAD/CANCELATION WITH THIS FORM OF CANCELATION (OK now - but could be better
        especially if we could Abort on the main thread / any thread; then could lose the cancel flag in our
        rep and just use the thread local rep for cancelation - same notaiton as thread cancel) ; and always have
        a worker thread object.
            --LGP 2023-12-06

@todo   MAYBE allow copy - but just document its a smart pointer and copy just increments refcount.
        NOT copy by value semantics.

@todo   Look at stuff I did I HeatthFrame progress code to automatically increase displayed progress values
        to monotonically when i have guesses - like for network activities. That should somehow integrate
        with this - maybe as an optional 'updater' module/adapter?

@todo   Not sure if we need to decompose into more component classes and use subtyping for stuff like
        thread support. It seems it mgiht work like this, but I'm sure it's not yet elegant.
Code-Status: Alpha

TODO:

Description:

 This module defines support for POSIX (and std c++ defined) Signals (not to be confused

with the 'Signals and slots' design pattern which is largely unrelated). (POSIX) Signals have all sorts of tricky rules for their manipulation/control. This doesn't eliminate those, but it makes most common cases much easier to handle safely. In particular, many cases of signals can be 'handled' not as signals (safe signal handlers).

TODO:

This API encourages that mistake. I changed the Service code to use SetSignalHandler - but That has the default of being hard to debug/non-modular. Maybe have a "SetDefaultHandler" or "SetFallbackHandler" - and that is invoked ONLY if no others? Or maybe a property of all handlers?

Description:

 This module defines support for POSIX (and std c++ defined) Signals (not to be confused

with the 'Signals and slots' design pattern which is largely unrelated).

TODO:

Note
Code-Status: Beta
Design Note (essentially) All exceptions thrown by Stroika (except where needed by quirks of underlying library integrated with) inherit from std::exception, or Stroika::Foundation::Execution::SilentException.

This means that any code which wishes to report an exception can catch these two types, and use the 'what()' method to report the text of the exception message.

Sadly, there is no documentation (I'm aware of) or specification of the character set/code page reported back by the what () on an exception. It tends to be ascii. Stroika guarantees that all exceptions it throws will use the current SDK characters (

See also
SDKString). But - its best to check for inheriting from Exception<>, since the SDK character set might not allow representing some unicode characters.

Typedef Documentation

◆ errno_t

The type of 'errno' variable.

Note
POSIX and C99 just say to assume its an int and doesn't define errno_t. But I find this type usage clearer.

Definition at line 53 of file Exceptions.h.

◆ QuickSynchronized

QuickSynchronized will always use a mutex which is quick, and not a cancelation point. It will typically be implemented using a std::mutex, or a SpinLock, whichever is faster. So - don't use this where you hold onto the lock for extended periods ;-).

Definition at line 774 of file Synchronized.h.

◆ TimedSynchronized

template<typename T >
using Stroika::Foundation::Execution::TimedSynchronized = typedef Synchronized<T, Synchronized_Traits<recursive_timed_mutex> >
Note
- TimedSynchronized doesn't do shared_locks - just a single mutex lock (that is recursive, and allows timeouts)

Definition at line 781 of file Synchronized.h.

◆ RWSynchronized

template<typename T >
using Stroika::Foundation::Execution::RWSynchronized = typedef Synchronized<T, Synchronized_Traits<shared_timed_mutex> >

RWSynchronized will always use some sort of mutex which supports multiple readers, and a single writer. Typically, using shared_mutex (or shared_timed_mutex).

Note
Use of RWSynchronized has HIGH PERFORMANCE OVERHEAD, and only makes sense when you have read locks held for a long time (and multiple threads doing so)

Definition at line 791 of file Synchronized.h.

Enumeration Type Documentation

◆ SequencePolicy

equivalent which of 4 types being used std::execution::sequenced_policy, parallel_policy, etc...

Much simpler to just have a single enum rather than these 4 classes. STL choice based on (probably more historical) C++ limitations with overloading (no constexpr) - not much point in that anymore, I don't think.

Enumerator
eSeq 

default case - not parallelized

Equivalent to std::seq, std::execution::sequenced_policy

..."a parallel algorithm's execution may not be parallelized. The invocations of element access functions in parallel algorithms invoked with this policy (usually specified as std::execution::seq) are indeterminately sequenced in the calling thread."

ePar 

must synchronize shared data, can use mutex (or atomics), cuz each parallel execution in real thread

Equivalent to std::par, std::execution::parallel_policy

..."parallel algorithm's execution may be parallelized. The invocations of element access functions in parallel algorithms invoked with this policy (usually specified as std::execution::par) are permitted to execute in either the invoking thread or in a thread implicitly created by the library to support parallel algorithm execution. Any such invocations executing in the same thread are indeterminately sequenced with respect to each other.

eParUnseq 

Unclear how this differs from eUnseq, but no locks allowed.

Equivalent to std::par_unseq , std::execution::parallel_unsequenced_policy

..."a parallel algorithm's execution may be parallelized, vectorized, or migrated across threads (such as by a parent-stealing scheduler). The invocations of element access functions in parallel algorithms invoked with this policy are permitted to execute in an unordered fashion in unspecified threads, and unsequenced with respect to one another within each thread..

eUnseq 

SIMD, no locks allowed.

Equivalent to std::unseq, std::execution::unsequenced_policy

..."a parallel algorithm's execution may be parallelized, vectorized, or migrated across threads (such as by a parent-stealing scheduler). The invocations of element access functions in parallel algorithms invoked with this policy are permitted to execute in an unordered fashion in unspecified threads, and unsequenced with respect to one another within each thread..

Definition at line 21 of file Foundation/Execution/Common.h.

◆ InternallySynchronized

The type InternallySynchronized is intended to be used as a flag to mark whether or not a given class/type/object is internally synchronized, or not.

It is typically provided as an optional argument to static New () methods, such as MemoryStream<>::New ()

Note
something marked eNotKnownInternallySynchronized - may in fact be internally synchronized.

Definition at line 53 of file Synchronized.h.

Function Documentation

◆ ThrowSystemErrNo()

void Stroika::Foundation::Execution::ThrowSystemErrNo ( int  sysErr)

treats sysErr as a platform-defined error number, and throws a SystemErrorException (subclass of @std::system_error) exception with it.

Precondition
sysErr != 0
Note
stdc++ uses 'int' for the type of this error number, but Windows generally defines the type to be DWORD.
Translates some throws to subclass of SystemErrorException like TimedException or other classes like bad_alloc.
From http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4659.pdf - "That object’s category() member shall return std::system_category() for errors originating from the operating system, or a reference to an implementation"
Example Usage
#if qStroika_Foundation_Common_Platform_POSIX
ThrowSystemErrNo (errno);
#elif qStroika_Foundation_Common_Platform_Windows
ThrowSystemErrNo (::GetLastError ()); // works with this type of error # - GetLastError () is default if no arg provided
ThrowSystemErrNo (::WSAGetLastError ()); // or this
#endif

See:

See also
ThrowPOSIXErrNo ();
Note
zero arg versions only defined for POSIX and Windows platforms, and there the default is the obvious value for each platform - errno and GetLastError(). It is still an assertion (require) error to call these when errno / GetLastError () would return 0.

Definition at line 175 of file Exceptions.inl.

◆ CaptureCurrentActivities()

Containers::Stack< Activity<> > Stroika::Foundation::Execution::CaptureCurrentActivities ( )

Returns a copyable preservable version of the current activities stack.

'render' each current activity on the current threads activity stack as a Activity<> (so String based), and return the full list as a copyable stack of activities.

Note
the intended purpose of this is to provide better 'context' for default exception messages, when exceptions are created/thrown.
the TOP of the static is the most specific activity, and the bottom of the stack is the initial, outermost task.

Definition at line 19 of file Activity.cpp.

◆ RunAll()

template<invocable<>... I>
void Stroika::Foundation::Execution::RunAll ( I...  functions)

Run all the argument functions (logically/potentially) in parallel, and wait until they all complete.

Could be implemented with std::async, or ThreadPool.

Definition at line 11 of file Async.inl.

◆ ThrowPOSIXErrNo()

void Stroika::Foundation::Execution::ThrowPOSIXErrNo ( errno_t  errNo = errno)

treats errNo as a POSIX errno value, and throws a SystemError (subclass of @std::system_error) exception with it.

Precondition
errNo != 0
Note
Translates some throws to subclass of SystemErrorException like TimedException or other classes like bad_alloc.
On a POSIX system, this amounts to a call to ThrowSystemErrNo. But even on a non-POSIX system, many APIs map their error numbers to POSIX error numbers so this can make sense to use. Also, on POSIX systems, its legal to call this with POSIX compatible extended (and therefore not POSIX) erorr nubmbers. In other words, you can call this with anything (except 0) you read out of errno on a POSIX system.
From http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/n4659.pdf - "If the argument ev corresponds to a POSIX errno value posv, the function shall return error_- condition(posv, generic_category()). Otherwise, the function"
this function takes errno as a default value because you almost always want to call it with the value from errno.

See:

See also
ThrowSystemErrNo ();

Definition at line 141 of file Exceptions.inl.

◆ ThrowPOSIXErrNoIfNegative()

template<typename INT_TYPE >
INT_TYPE Stroika::Foundation::Execution::ThrowPOSIXErrNoIfNegative ( INT_TYPE  returnCode)

Look at the argument value and if < 0,ThrowPOSIXErrNo (), and otherwise return it.

Note
Many POSIX - APIs - return a number which is zero if good, or -1 (or sometimes defined negative) if errno is set and there is an error. This function is useful for wrapping calls to those style functions. It checks if the argument result is negative (so -1 covers that) and throws and a POSIX (generic_error) SystemErrorException.

Definition at line 162 of file Exceptions.inl.

◆ Handle_ErrNoResultInterruption()

template<typename CALL >
auto Stroika::Foundation::Execution::Handle_ErrNoResultInterruption ( CALL  call) -> decltype (call ())

Handle UNIX EINTR system call behavior - fairly transparently - just effectively removes them from the set of errors that can be returned.

Run the given (argument) call. After each call, invoke Thread::CheckForInterruption (). If the call returns < 0 and errno == EINTR, repeat the call. If the result was < 0, but errno != EINTR, then ThrowErrNoIfNegative (); Then return the result.

Note
The only HITCH with respect to automatically handling interruptability is that that its handled by 'restarting' the argument 'call' That means if it was partially completed, the provider of 'call' must accommodate that fact (use mutable lambda).

This behavior is meant to work with the frequent POSIX API semantics of a return value of < 0 implying an error, and < 0 but errno == EINTR means retry the call. This API also provides a cancelation point - so it makes otherwise blocking calls (like select, or read) work well with thread interruption.

Note
Cancelation Point

Definition at line 202 of file Exceptions.inl.

◆ ThrowPOSIXErrNoIfNull()

void Stroika::Foundation::Execution::ThrowPOSIXErrNoIfNull ( void *  returnValue)

Check the argument 'return value' from some function, and if its null, throw a SystemError exception with the current errno value.

Note
rarely useful, but some POSIX APIs such as getcwd() do return null on error.

Definition at line 217 of file Exceptions.inl.

◆ GetAssociatedErrorCode()

optional< error_code > Stroika::Foundation::Execution::GetAssociatedErrorCode ( const exception_ptr &  e)
noexcept

This checks if the given exception_ptr is of a type that contains an error code, and if so it extracts the error code, and returns it (else nullopt).

Example Usage
try {
/// do something that throws
}
catch (...) {
if (auto err = GetAssociatedErrorCode (current_exception ())) {
if (*err == errc::no_such_device) {
// This can happen on Linux when you start before you have a network connection - no problem - just keep trying
DbgTrace ("Got exception (errno: ENODEV) - while joining multicast group, so try again");
goto Again;
}
else {
}
}
}
#define DbgTrace
Definition Trace.h:309
void Sleep(Time::Duration seconds2Wait)
Definition Sleep.cpp:18
optional< error_code > GetAssociatedErrorCode(const exception_ptr &e) noexcept

Definition at line 226 of file Exceptions.cpp.

◆ TranslateExceptionToOptional()

template<typename F >
auto Stroika::Foundation::Execution::TranslateExceptionToOptional ( F &&  f) -> optional<remove_cvref_t<invoke_result_t<F>>>

Wrap the the argument function (typically a lambda) in an OPTIONAL of the argument type, and return nullopt - dropping the exception on the floor.

Definition at line 230 of file Exceptions.inl.

◆ Finally()

template<Common::INoThrowInvocable FUNCTION>
auto Stroika::Foundation::Execution::Finally ( FUNCTION &&  f) -> Private_::FinallySentry<FUNCTION>

This helpful utility to plug a missing feature from C++11 - to have a block of code run at the end of a scope - regardless of whether you use normal exit or exception based exit.

This has some defects: o The syntax is ugly - the cleanup having to be declared BEFORE the block instead of afterwards (languages like C# with try/finally the finally goes at the end)

o Exceptions inside of cleanupCodeBlock must be suppressed

Inspired by: http://nerds-central.blogspot.com/2012/03/c11-trycatchfinally-pattern-using-raii.html

Note
SEE https://en.cppreference.com/w/cpp/experimental/scope_exit https://en.cppreference.com/w/cpp/experimental/scope_fail https://en.cppreference.com/w/cpp/experimental/scope_success (these may replace Finally - success/fail variants maybe better, and scope_exit I think basically the same, except not sure always available)
For cleanup which is important/critical to be completed, its sometimes wise to include Thread::SuppressInterruptionInContext suppressThreadInterrupts; in the function body
This is (now) done in such a way that no locks are used or memory allocated, except if argument lambda uses them/does it.
This automatically suppresses any expressions triggered in the argument function, but its usually best to pass in a noexcept lambda (future versions may be more efficient in that case).
Important parts of why this works: use auto so 'type' (size of struct for params) is dynamically calculated, and on stack with no memory allocation/indirection; and NAMED rvalue-reference so that its lifetime extends to the end of the scope in which its contained.
Example Usage
[[maybe_unused]]auto&& cleanup = Finally ([] () noexcept { Require (not sKnownBadBeforeMainOrAfterMain_); });
auto Finally(FUNCTION &&f) -> Private_::FinallySentry< FUNCTION >
Definition Finally.inl:31

Definition at line 31 of file Finally.inl.

◆ DefaultLoggingFatalErrorHandler()

void Stroika::Foundation::Execution::DefaultLoggingFatalErrorHandler ( const Characters::SDKChar msg)
noexcept

Sensible argument to RegisterDefaultFatalErrorHandlers, if using Logger (but beware - caller must assure Logger::Activate called appropriately)

◆ DefaultLoggingCrashSignalHandler()

void Stroika::Foundation::Execution::DefaultLoggingCrashSignalHandler ( Execution::SignalID  signal)
noexcept

Sensible argument to SignalHandlerRegistry::Get ().SetStandardCrashHandlerSignals(...), if using Logger (but beware - caller must assure Logger::Activate called appropriately)

Definition at line 602 of file Logger.cpp.

◆ GetEXEDir()

filesystem::path Stroika::Foundation::Execution::GetEXEDir ( )

The directory where the executable that is running this code is located. If this code is compiled into a DLL, this returns the executable directory for the underlying process/executable (not the DLL/so file).

Definition at line 43 of file Module.cpp.

◆ GetEXEPath() [1/2]

filesystem::path Stroika::Foundation::Execution::GetEXEPath ( )

The path where the executable that is running this code is located. If this code is compiled into a DLL, this returns the executable for the underlying process/executable (not the DLL/so file).

Definition at line 53 of file Module.cpp.

◆ GetEXEPath() [2/2]

filesystem::path Stroika::Foundation::Execution::GetEXEPath ( pid_t  processID)

Return the full path to the given process (throws if not found).

NYI for WINDOWS.

Definition at line 101 of file Module.cpp.

◆ FindExecutableInPath()

optional< filesystem::path > Stroika::Foundation::Execution::FindExecutableInPath ( const filesystem::path &  fn)

If fn refers to an executable - return it (using kPATH, and kPathEXT as appropriate)

If fn is an absolute path, use that (possibly with suffixes appended). If fn is not absolute, try appending it to each path from kPATH, and redo same check.

On Windows, if ext is missing, also check kPathEXT

If no matches, return nullopt.

Definition at line 245 of file Module.cpp.

◆ IsProcessRunning()

bool Stroika::Foundation::Execution::IsProcessRunning ( pid_t  pid)

Return true, if the pid can be verified to be running, false if verified not running.

Note
This obviously can be a race as processes can come and go quickly

Definition at line 23 of file Foundation/Execution/Process.cpp.

◆ MakeInputStreamWithProgress()

template<typename T >
Streams::InputStream::Ptr< T > Stroika::Foundation::Execution::MakeInputStreamWithProgress ( const Streams::InputStream::Ptr< T > &  in,
ProgressMonitor::Updater  progress 
)

Take an input-stream object, and produce another identical, except that it updates the argument progress updater object. Note this works better if the argument 'in' supports RemainingLength, but guesses otherwise.

Definition at line 163 of file ProgressMonitor.inl.

◆ SendSignal()

errno_t Stroika::Foundation::Execution::SendSignal ( thread::native_handle_type  target,
SignalID  signal 
)

Send the given signal to a specific thread (within this process)

This function returns an errno error number. o if the error number is ESRCH, this just menans the target thread doesn't exist anymore, whcih can easily happen (race) - like if you are sending an abort to a thread but it exits first.

o other error numbres - for now - generate an assertion error. The function returns zero if no error

◆ Sleep()

void Stroika::Foundation::Execution::Sleep ( Time::Duration  seconds2Wait)

The portable Sleep() function - will wait the given amount of time - blocking the calling thread. It CAN be interrupted (not talking about thread interrupt - e.g. POSIX signal). If interrupted, one overload will return the amount of time remaining, allowing easy re-sleeping. The other overload (/1) - will check for aborting, but otherwise keep sleeping through interrupts until the time has elapsed.

See also
SleepUntil

Sleep\1: will restart sleeping to use up the full given sleep time, if interrupted (unless thread interruption causes throw) Sleep\2: may not use up the entire time given as argument, and if not, will place in remainingInSleep the time remaining.

Example Usage
Note
Sleep (0) will still yield the processor (so like std::thread::yield ())
Precondition
seconds2Wait >= 0
Postcondition
*remainingInSleep <= seconds2Wait
*remainingInSleep >= 0
Note
Thread-Safety Internally-Synchronized-Thread-Safety
Cancelation Point
Very similar to std::this_thread::sleep_for () - except for the overload returning remaining amount, and cancelation support

Definition at line 18 of file Sleep.cpp.

◆ SleepUntil()

void Stroika::Foundation::Execution::SleepUntil ( Time::TimePointSeconds  untilTickCount)

Wait until the tickCount is >= the given value.

Example Usage
Time::DurationSeconds startedAt = Time::GetTickCount ();
do_something_dont_know_how_long_it_will_take();
Execution::SleepUntil (1.0s + startedAt); // make sure do_something_dont_know_how_long_it_will_take () took at least one second
chrono::duration< double > DurationSeconds
chrono::duration<double> - a time span (length of time) measured in seconds, but high precision.
Definition Realtime.h:57
void SleepUntil(Time::TimePointSeconds untilTickCount)
Definition Sleep.inl:91
See also
Sleep ();
Note
Cancelation Point
Unlike Sleep () - this may or may not yield.
SleepUntil restarts if interrupted, so if it returns, it will return after untilTickCount
This may or may not end up calling Sleep(). It is not an error to call with a tickCount which has already passed: it just returns quickly, and may not yield.
Very similar to std::this_thread::sleep_until () - except for the cancelation support

Definition at line 91 of file Sleep.inl.

◆ Throw()

template<typename T >
void Stroika::Foundation::Execution::Throw ( T &&  e2Throw)

identical to builtin C++ 'throw' except that it does helpful, type dependent DbgTrace() messages first

Utility to call a Trace message (hopefully an appropriate one) for an exception being thrown... But this function is also specialized to do call D::Throw() for several types - which CAN translate the kind of exception throw. For example, for Platform:Windows::Exception - ERROR_OUTOFMEMORY is translated to std::bad_alloc ().

ONLY the first variation (with no traceMessage) is template specialized. The overloads which take an extra message are JUST for convenience, and vector through the 1-arg overload - so as to get is specialization.

Definition at line 43 of file Throw.inl.

◆ ReThrow()

void Stroika::Foundation::Execution::ReThrow ( )

Just a regular C++ rethrow, but with a DbgTrace message...

Definition at line 75 of file Throw.inl.

◆ ThrowIfNull()

template<equality_comparable_with< nullptr_t > T, typename E >
void Stroika::Foundation::Execution::ThrowIfNull ( const T &  p,
const E &  e 
)

If the first argument is null, throw the second argument exception (which defaults to bad_alloc)

Definition at line 124 of file Throw.inl.

◆ ThrowTimeoutExceptionAfter()

template<typename EXCEPTION >
void Stroika::Foundation::Execution::ThrowTimeoutExceptionAfter ( Time::TimePointSeconds  afterTickCount,
EXCEPTION &&  exception2Throw 
)

Throw TimeOutException if the @Time::GetTickCount () is >= the given value.

This function facilitates writing code like: Time::DurationSeconds timeoutAfter = Time::GetTickCount () + 1.0; do_someting_dont_know_how_long_it_will_take(); Execution::ThrowTimeoutExceptionAfter (timeoutAfter);

Note
Cancelation Point

Definition at line 31 of file TimeOutException.inl.

◆ TryLockUntil()

template<typename TIMED_MUTEX , typename EXCEPTION >
void Stroika::Foundation::Execution::TryLockUntil ( TIMED_MUTEX &  m,
Time::TimePointSeconds  afterTickCount,
EXCEPTION &&  exception2Throw 
)

Translate timed_mutex, or recursive_timed_mutex try_lock_until () calls which fail into TimeOutException exceptions.

Definition at line 50 of file TimeOutException.inl.

◆ ThrowIfTimeout()

template<typename EXCEPTION >
void Stroika::Foundation::Execution::ThrowIfTimeout ( cv_status  conditionVariableStatus,
EXCEPTION &&  exception2Throw 
)
Note
- this function may not be called outside the context of a running main.

◆ UniqueLock()

template<typename TIMED_MUTEX , typename EXCEPTION >
unique_lock< TIMED_MUTEX > Stroika::Foundation::Execution::UniqueLock ( TIMED_MUTEX &  m,
const chrono::duration< double > &  d,
EXCEPTION &&  exception2Throw 
)

Simple wrapper on construction of unique_lock<TIMED_MUTEX> - which translates the timeout into a TimeOutException.

Note
if this function returns (doesn't throw) - the required unique_lock<> OWNS the mutex.
See also
also TryLockUntil
also TimedLockGuard

Definition at line 85 of file TimeOutException.inl.

Variable Documentation

◆ kPath

const LazyInitialized< Sequence< filesystem::path > > Stroika::Foundation::Execution::kPath
extern
Initial value:
{[] () -> Sequence<filesystem::path> {
if (const char* env_p = std::getenv ("PATH")) {
String pathVar = String::FromNarrowSDKString (env_p);
}
return {};
}}

The set of system locations to look for an executable (note order matters, which is why this is a Sequence)

Definition at line 144 of file Module.cpp.

◆ kRawEnvironment

const LazyInitialized< Mapping< SDKString, SDKString > > Stroika::Foundation::Execution::kRawEnvironment
extern

convert getenv() to a Mapping of SDKString (in case some issue with charactor set conversion)

Note
LazyInitialized so if not used, nearly zero cost

Definition at line 180 of file Module.cpp.

◆ kEnvironment

const LazyInitialized< Mapping< String, String > > Stroika::Foundation::Execution::kEnvironment
extern
Initial value:
{[] () -> Mapping<String, String> {
Mapping<String, String> r;
for (auto i : kRawEnvironment ()) {
r.Add (String::FromSDKString (i.fKey), String::FromSDKString (i.fValue));
}
return r;
}}
const LazyInitialized< Containers::Mapping< Characters::SDKString, Characters::SDKString > > kRawEnvironment
convert getenv() to a Mapping of SDKString (in case some issue with charactor set conversion)
Definition Module.cpp:180

convert getenv() to a Mapping of Strings for easier access

Note
LazyInitialized so if not used, nearly zero cost

Definition at line 232 of file Module.cpp.

◆ kSpinLock_IsFasterThan_mutex

constexpr bool Stroika::Foundation::Execution::kSpinLock_IsFasterThan_mutex = true
constexpr

SpinLock and mutex can be nearly used interchangeably. Oftentimes, users will want to define a typedef which selects the faster implementation.

Note
Stroika 2.0a155 and earlier - Execution::kSpinLock_IsFasterThan_mutex was always true
Stroika 2.0a156 and later - due to threadFence and http://stroika-bugs.sophists.com/browse/STK-494 - SpinLock slowed slightly, but its still notably faster (with the default barrier style) on gcc/unix/windows (x86 only tested).

Definition at line 30 of file SpinLock.h.