#ifndef PUPPET_APPLICATION_H #define PUPPET_APPLICATION_H #include #include #include #include #include #include #include namespace sscl { class PuppetApplication : public std::enable_shared_from_this { public: PuppetApplication( const std::vector> &threads); ~PuppetApplication() = default; co::NonViralNonPostingInvoker joltAllPuppetThreadsCReq( std::exception_ptr &exceptionPtr, std::function callback); co::NonViralNonPostingInvoker startAllPuppetThreadsCReq( std::exception_ptr &exceptionPtr, std::function callback); co::NonViralNonPostingInvoker pauseAllPuppetThreadsCReq( std::exception_ptr &exceptionPtr, std::function callback); co::NonViralNonPostingInvoker resumeAllPuppetThreadsCReq( std::exception_ptr &exceptionPtr, std::function callback); co::NonViralNonPostingInvoker exitAllPuppetThreadsCReq( std::exception_ptr &exceptionPtr, std::function callback); // CPU distribution method void distributeAndPinThreadsAcrossCpus(); protected: // Collection of PuppetThread instances std::vector> componentThreads; /** * Indicates whether all puppet threads have been JOLTed at least once. * * JOLTing serves two critical purposes: * * 1. **Global Constructor Sequencing**: Since pthreads begin executing while * global constructors are still being executed, globally defined pthreads * cannot depend on global objects having been constructed. JOLTing is done * by the CRT's main thread within main(), which provides a sequencing * guarantee that global constructors have been called. * * 2. **shared_from_this Safety**: shared_from_this() requires a prior * shared_ptr handle to be established. The global list of * shared_ptr guarantees that at least one shared_ptr to * each ComponentThread has been initialized before JOLTing occurs. * * This flag ensures that JOLTing happens exactly once and provides * a synchronization point for the entire system initialization. */ bool threadsHaveBeenJolted = false; }; } // namespace sscl #endif // PUPPET_APPLICATION_H