mirror of
https://github.com/latentPrion/libspinscale.git
synced 2026-02-27 14:36:04 +00:00
Compare commits
3 Commits
e77ecd447d
...
01a9c6ecc9
| Author | SHA1 | Date | |
|---|---|---|---|
| 01a9c6ecc9 | |||
| e813962168 | |||
| a3931d7b8f |
@@ -34,9 +34,9 @@ public:
|
||||
{ break; }
|
||||
|
||||
/** EXPLANATION:
|
||||
* In the mrntt and mind thread loops we call checkException() after
|
||||
* run() returns, but we don't have to do that here because
|
||||
* setException() calls stop.
|
||||
* In the puppeteer and mind thread loops we call checkException()
|
||||
* after run() returns, but we don't have to do that here because
|
||||
* setException() calls stop().
|
||||
*
|
||||
* So if an exception is set on our thread, we'll break out of this
|
||||
* loop due to the check for stopped() above, and that'll take us
|
||||
|
||||
@@ -10,7 +10,20 @@
|
||||
namespace sscl {
|
||||
|
||||
class ComponentThread;
|
||||
class PuppetThread;
|
||||
|
||||
/** EXPLANATION:
|
||||
* Components are API-exposing sub-components of an application. They are used
|
||||
* aggregate the resources and API of some logically distinct sub-system into
|
||||
* a single abstract entity. Basically, a component is a way to bind some APIs
|
||||
* and resources to a particular thread. Ideally, all accesses to the resources
|
||||
* of a component should be made through the component's APIs.
|
||||
*
|
||||
* Multiple components can share the same thread; and for this reason, each
|
||||
* component must be supplied with a reference to the thread it shares.
|
||||
* This amounts to saying that a single thread may expose and serve multiple
|
||||
* APIs.
|
||||
*/
|
||||
class Component
|
||||
{
|
||||
public:
|
||||
@@ -29,7 +42,7 @@ class PuppetComponent
|
||||
public:
|
||||
PuppetComponent(
|
||||
PuppetApplication &parent,
|
||||
const std::shared_ptr<ComponentThread> &thread);
|
||||
const std::shared_ptr<PuppetThread> &thread);
|
||||
~PuppetComponent() = default;
|
||||
|
||||
public:
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
namespace sscl {
|
||||
|
||||
class MarionetteThread;
|
||||
class PuppeteerThread;
|
||||
class PuppetThread;
|
||||
|
||||
// ThreadId is a generic type - application-specific enums should be defined elsewhere
|
||||
@@ -45,7 +45,7 @@ public:
|
||||
|
||||
static const std::shared_ptr<ComponentThread> getSelf(void);
|
||||
static bool tlsInitialized(void);
|
||||
static std::shared_ptr<MarionetteThread> getMrntt();
|
||||
static std::shared_ptr<PuppeteerThread> getMrntt();
|
||||
|
||||
typedef void (mainFn)(ComponentThread &self);
|
||||
|
||||
@@ -66,18 +66,18 @@ public:
|
||||
std::atomic<bool> keepLooping;
|
||||
};
|
||||
|
||||
class MarionetteThread
|
||||
: public std::enable_shared_from_this<MarionetteThread>,
|
||||
class PuppeteerThread
|
||||
: public std::enable_shared_from_this<PuppeteerThread>,
|
||||
public ComponentThread
|
||||
{
|
||||
public:
|
||||
MarionetteThread(ThreadId id = 0)
|
||||
PuppeteerThread(ThreadId id = 0)
|
||||
: ComponentThread(id),
|
||||
thread(main, std::ref(*this))
|
||||
{
|
||||
}
|
||||
|
||||
static void main(MarionetteThread& self);
|
||||
static void main(PuppeteerThread& self);
|
||||
void initializeTls(void);
|
||||
|
||||
public:
|
||||
@@ -154,14 +154,15 @@ public:
|
||||
class ThreadLifetimeMgmtOp;
|
||||
};
|
||||
|
||||
namespace mrntt {
|
||||
extern std::shared_ptr<MarionetteThread> thread;
|
||||
namespace pptr {
|
||||
extern std::shared_ptr<PuppeteerThread> thread;
|
||||
|
||||
// Forward declaration for marionette thread ID management
|
||||
// Forward declaration for puppeteer thread ID management
|
||||
// Must be after sscl namespace so ThreadId is defined
|
||||
extern ThreadId marionetteThreadId;
|
||||
void setMarionetteThreadId(ThreadId id);
|
||||
} // namespace mrntt
|
||||
}
|
||||
extern ThreadId puppeteerThreadId;
|
||||
void setPuppeteerThreadId(ThreadId id);
|
||||
} // namespace pptr
|
||||
|
||||
} // namespace sscl
|
||||
|
||||
#endif // COMPONENT_THREAD_H
|
||||
|
||||
@@ -8,9 +8,10 @@
|
||||
|
||||
namespace sscl {
|
||||
|
||||
class MarionetteThread;
|
||||
class PuppeteerThread;
|
||||
extern std::shared_ptr<sscl::PuppeteerThread> thread;
|
||||
|
||||
namespace mrntt {
|
||||
namespace pptr {
|
||||
|
||||
class MarionetteComponent
|
||||
: public sscl::Component
|
||||
@@ -31,14 +32,12 @@ private:
|
||||
class TerminationEvent;
|
||||
};
|
||||
|
||||
extern std::shared_ptr<sscl::MarionetteThread> thread;
|
||||
|
||||
extern std::atomic<int> exitCode;
|
||||
void exitMarionetteLoop();
|
||||
void marionetteFinalizeReqCb(bool success);
|
||||
extern MarionetteComponent mrntt;
|
||||
|
||||
} // namespace mrntt
|
||||
} // namespace pptr
|
||||
|
||||
struct CrtCommandLineArgs
|
||||
{
|
||||
|
||||
@@ -10,13 +10,13 @@ Component::Component(const std::shared_ptr<ComponentThread> &thread)
|
||||
}
|
||||
|
||||
PuppetComponent::PuppetComponent(
|
||||
PuppetApplication &parent, const std::shared_ptr<ComponentThread> &thread)
|
||||
PuppetApplication &parent, const std::shared_ptr<PuppetThread> &thread)
|
||||
: Component(thread),
|
||||
parent(parent)
|
||||
{
|
||||
}
|
||||
|
||||
namespace mrntt {
|
||||
namespace pptr {
|
||||
|
||||
MarionetteComponent::MarionetteComponent(
|
||||
const std::shared_ptr<sscl::ComponentThread> &thread)
|
||||
@@ -24,5 +24,6 @@ MarionetteComponent::MarionetteComponent(
|
||||
{
|
||||
}
|
||||
|
||||
} // namespace mrntt
|
||||
} // namespace pptr
|
||||
|
||||
} // namespace sscl
|
||||
|
||||
@@ -13,35 +13,33 @@
|
||||
|
||||
namespace sscl {
|
||||
|
||||
namespace mrntt {
|
||||
// Global variable to store the marionette thread ID
|
||||
// Default value is 0, but should be set by application code via setMarionetteThreadId()
|
||||
ThreadId marionetteThreadId = 0;
|
||||
namespace pptr {
|
||||
/* Global variable to store the puppeteer thread ID
|
||||
* Default value is 0, but should be set by application code via
|
||||
* setPuppeteerThreadId().
|
||||
*/
|
||||
ThreadId puppeteerThreadId = 0;
|
||||
/* Global puppeteer thread instance - defined here but initialized by
|
||||
* application code.
|
||||
*/
|
||||
std::shared_ptr<PuppeteerThread> thread;
|
||||
|
||||
void setMarionetteThreadId(ThreadId id)
|
||||
void setPuppeteerThreadId(ThreadId id)
|
||||
{
|
||||
marionetteThreadId = id;
|
||||
puppeteerThreadId = id;
|
||||
}
|
||||
} // namespace mrntt
|
||||
|
||||
} // namespace sscl
|
||||
|
||||
namespace sscl {
|
||||
} // namespace pptr
|
||||
|
||||
thread_local std::shared_ptr<ComponentThread> thisComponentThread;
|
||||
|
||||
namespace mrntt {
|
||||
// Global marionette thread instance - defined here but initialized by application
|
||||
std::shared_ptr<MarionetteThread> thread;
|
||||
} // namespace mrntt
|
||||
|
||||
// Implementation of static method
|
||||
std::shared_ptr<MarionetteThread> ComponentThread::getMrntt()
|
||||
std::shared_ptr<PuppeteerThread> ComponentThread::getMrntt()
|
||||
{
|
||||
return sscl::mrntt::thread;
|
||||
return sscl::pptr::thread;
|
||||
}
|
||||
|
||||
void MarionetteThread::initializeTls(void)
|
||||
void PuppeteerThread::initializeTls(void)
|
||||
{
|
||||
thisComponentThread = shared_from_this();
|
||||
}
|
||||
@@ -179,24 +177,24 @@ void PuppetThread::joltThreadReq(
|
||||
* We also can't use getSelf() as yet for the same reason: getSelf()
|
||||
* requires TLS to be set up.
|
||||
*
|
||||
* To obtain a sh_ptr to the caller, we just supply the mrntt thread since
|
||||
* JOLT is always invoked by the mrntt thread. The JOLT sequence that the
|
||||
* CRT main() function invokes on the mrntt thread is special since it
|
||||
* supplies cmdline args and envp.
|
||||
* To obtain a sh_ptr to the caller, we just supply the puppeteer thread
|
||||
* since JOLT is always invoked by the puppeteer thread. The JOLT sequence
|
||||
* that the CRT main() function invokes on the puppeteer thread is special
|
||||
* since it supplies cmdline args and envp.
|
||||
*
|
||||
* To obtain a sh_ptr to the target thread, we use the selfPtr parameter
|
||||
* passed in by the caller.
|
||||
*/
|
||||
if (id == sscl::mrntt::marionetteThreadId)
|
||||
if (id == sscl::pptr::puppeteerThreadId)
|
||||
{
|
||||
throw std::runtime_error(std::string(__func__)
|
||||
+ ": invoked on mrntt thread");
|
||||
+ ": invoked on puppeteer thread");
|
||||
}
|
||||
|
||||
std::shared_ptr<MarionetteThread> mrntt = sscl::mrntt::thread;
|
||||
std::shared_ptr<PuppeteerThread> puppeteer = sscl::pptr::thread;
|
||||
|
||||
auto request = std::make_shared<ThreadLifetimeMgmtOp>(
|
||||
mrntt, selfPtr, callback);
|
||||
puppeteer, selfPtr, callback);
|
||||
|
||||
this->getIoService().post(
|
||||
STC(std::bind(
|
||||
@@ -238,10 +236,10 @@ void PuppetThread::exitThreadReq(Callback<threadLifetimeMgmtOpCbFn> callback)
|
||||
|
||||
void PuppetThread::pauseThreadReq(Callback<threadLifetimeMgmtOpCbFn> callback)
|
||||
{
|
||||
if (id == sscl::mrntt::marionetteThreadId)
|
||||
if (id == sscl::pptr::puppeteerThreadId)
|
||||
{
|
||||
throw std::runtime_error(std::string(__func__)
|
||||
+ ": invoked on mrntt thread");
|
||||
+ ": invoked on puppeteer thread");
|
||||
}
|
||||
|
||||
std::shared_ptr<ComponentThread> caller = getSelf();
|
||||
@@ -257,10 +255,10 @@ void PuppetThread::pauseThreadReq(Callback<threadLifetimeMgmtOpCbFn> callback)
|
||||
|
||||
void PuppetThread::resumeThreadReq(Callback<threadLifetimeMgmtOpCbFn> callback)
|
||||
{
|
||||
if (id == sscl::mrntt::marionetteThreadId)
|
||||
if (id == sscl::pptr::puppeteerThreadId)
|
||||
{
|
||||
throw std::runtime_error(std::string(__func__)
|
||||
+ ": invoked on mrntt thread");
|
||||
+ ": invoked on puppeteer thread");
|
||||
}
|
||||
|
||||
// Post to the pause_io_service to unblock the paused thread
|
||||
|
||||
Reference in New Issue
Block a user