They are posted to Marionette.
* We also fixed callOriginCb invocations;
* Also made posted CBs use std::bind instead of greedily
early-invoking the CB on the servicing thread's stack.
We now have mind::initialize/finalizeReq post their requests
to Mrntt instead of executing on the caller's thread context.
We also fixed the way that we invoke callbacks by properly wrapping
it in a std::bind.
We no longer need them because we now have
mrntt::mrntt.finalizeReq(), which does a more holistic job of
shutting down Marionette (and thus, ultimately, Salmanoff).
If even one step in Body.initializeReq was executed at all, then
whether or not it succeeded, we consider the body component to have
been initialized, at least with respect to whether finalizeReq
ought to run.
We now run body.finalizeReq even if body.init wasn't called. We'll
do a finer-grained check on each aspect of Body that needs to be
finalized now. This check was too large-grained.
This leverages the new clean dynamic allocation of the globalMind
object to make the mrntt::main and SMO's initialization and
shutdown much cleaner. We no longer concern ourselves with
shutting down the Mind threads inside of mrntt::main, but rather
we leave that state machine to the Mind class and Mrntt component.
This makes the initialization sequence much cleaner and conceptually
well encapsulated.
We also now dynamically allocate the Mind objects. They're allocated
dynamically by Mrntt inside of initializeReq. This means that we no
longer have to worry about jolting and cleaning up the running threads
of global mind object even when we never explicitly called
Mind.initializeReq.
Along with other conceptual improvements to our abstractions, this
patch also gets us to a real "end of program initialization" point
for the first time.
We now allocate globalMind locally inside of marionetteMain. Why?
Before now, we had an asymmetric threading situation where the
globalMind's threads were initialized at during global constructor
invocation and not on demand. This meant that we had to shut down
those threads even if we had never got to the point of calling
Mind::initializeReq.
This significantly complicated our shutdown sequence since we had
to factor in the lifetime of the std::thread objects inside of the
ComponentThreads which were inside of the globalMind object.
Now, if we hadn't called Mind::initializeReq, we don't have to
perform any Mind::finalizeReq or adjacent operations. Shutdown is
symmetrically mirrored against the operations we actually performed
during execution.
We introduced some complexity by splitting ComponentThreads into
two derivative types (MindThread and MarionetteThread) but I think
in the long term we'll be able to massage this split into a much
cleaner situation overall.
In Mrntt, we now initialize Mind:: object threads before calling
initializeSalmanoffReq().
We've also propagated the spinscale async pattern into the Mind
class.
This class enables us to consistently represent continuations
that are intended to be posted on a particular target handling
thread. It hols a sh_ptr to the caller so that the target thread
can re-enqueue the response on the caller after processing the
REQ/IND op.