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 |
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 (
TODO:
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:
@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.
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:
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 (
typedef int Stroika::Foundation::Execution::errno_t |
The type of 'errno' variable.
Definition at line 53 of file Exceptions.h.
using Stroika::Foundation::Execution::QuickSynchronized = typedef conditional_t<kSpinLock_IsFasterThan_mutex, Synchronized<T, Synchronized_Traits<SpinLock> >, Synchronized<T, Synchronized_Traits<mutex> >> |
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.
using Stroika::Foundation::Execution::TimedSynchronized = typedef Synchronized<T, Synchronized_Traits<recursive_timed_mutex> > |
Definition at line 781 of file Synchronized.h.
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).
Definition at line 791 of file Synchronized.h.
|
strong |
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.
Definition at line 21 of file Foundation/Execution/Common.h.
|
strong |
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 ()
Definition at line 53 of file Synchronized.h.
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.
See:
Definition at line 175 of file Exceptions.inl.
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.
Definition at line 19 of file Activity.cpp.
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.
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.
See:
Definition at line 141 of file Exceptions.inl.
INT_TYPE Stroika::Foundation::Execution::ThrowPOSIXErrNoIfNegative | ( | INT_TYPE | returnCode | ) |
Look at the argument value and if < 0,ThrowPOSIXErrNo (), and otherwise return it.
Definition at line 162 of file Exceptions.inl.
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.
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.
Definition at line 202 of file Exceptions.inl.
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.
Definition at line 217 of file Exceptions.inl.
|
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).
Definition at line 226 of file Exceptions.cpp.
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.
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
Definition at line 31 of file Finally.inl.
|
noexcept |
Sensible argument to RegisterDefaultFatalErrorHandlers, if using Logger (but beware - caller must assure Logger::Activate called appropriately)
|
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.
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.
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.
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.
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.
bool Stroika::Foundation::Execution::IsProcessRunning | ( | pid_t | pid | ) |
Return true, if the pid can be verified to be running, false if verified not running.
Definition at line 23 of file Foundation/Execution/Process.cpp.
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.
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
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.
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.
void Stroika::Foundation::Execution::SleepUntil | ( | Time::TimePointSeconds | untilTickCount | ) |
Wait until the tickCount is >= the given value.
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.
void Stroika::Foundation::Execution::ReThrow | ( | ) |
void Stroika::Foundation::Execution::ThrowIfNull | ( | const T & | p, |
const E & | e | ||
) |
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);
Definition at line 31 of file TimeOutException.inl.
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.
void Stroika::Foundation::Execution::ThrowIfTimeout | ( | cv_status | conditionVariableStatus, |
EXCEPTION && | exception2Throw | ||
) |
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.
Definition at line 85 of file TimeOutException.inl.
|
extern |
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.
|
extern |
convert getenv() to a Mapping of SDKString (in case some issue with charactor set conversion)
Definition at line 180 of file Module.cpp.
|
extern |
convert getenv() to a Mapping of Strings for easier access
Definition at line 232 of file Module.cpp.
|
constexpr |
SpinLock and mutex can be nearly used interchangeably. Oftentimes, users will want to define a typedef which selects the faster implementation.
Definition at line 30 of file SpinLock.h.