We now create the sh_ptr to the copy of a lockvoker object in its
own supplied register method. This enables us to retain type safety
when calling make_shared, by copying the most derived version of
the lockvoker object. Then we can pass in the LockerAndInvokerBase
to the rest of the call chain.
The dependency graph class enables us to perform analysis on the
qutex acquisition history data. By generating the graph and
detecting cycles in it, we can find true gridlocks.
We use this graph analysis code to implement the algorithmically
complete version of the gridlock detector.
We add the new Qutex acquisision history tracker that allows us
to dynamically detect qutex gridlocks. We've integrated it into
LockerAndInvoker::operator() in a preliminary way.
We also moved all of the trace*ForGridlockOn() methods into the
new QutexAcquisitionHistoryTracker singleton class. They're
more appropriately located there. They're still unimplemented
though.
We add the skeleton of a correct history tracer for gridlocks. The
previous history tracer made the incorrect assumption that we would
find the foreign sequence's currently desired LockSet inside of the
lockvoker that it has stored inside of Qutex::currOwner.
This ensures that the Lockvoker object we access from currOwner
remains valid past the lifetime of the Lockvoker object that
gets copied and invoked by boost::asio
We added the code to trace all the contins linked to a particular
Lockvoker, into SerializedAsyncContinuation. This basically
ensures that we'll almost never deal with a deadlock. So cool.
We previously passed a sh_ptr to the caller's contin as arguments
to the std::bind() callable. In order for us to be able to trace
deadlocks, we need to be able to access them explicitly.
So here's that change.
We added a timestamp to each Lockvoker so that we can detect when
a lockvoker has been in a qutex for "too long", where "too long"
is defined arbitrarily as 500ms.
Next we're going to change the way we create callbacks to enable
us to more explicitly access the sh_ptr<AsyncContin> via
the callback object.
We now detect that a deadlock is likely when
CONFIG_DEBUG_QUTEX_DEADLOCK_TIMEOUT_MS has elapsed. This is the
preliminary work required to do a backtrace through the call
stack and figure out if a deadlock has really occured.
To do this, we'd have to go through the async call chain and
search for a previous caller which acquired the same qutex as
the one that first failed during this Lockvoker LockSet acquisition
attempt.
CONT_SET_EXC: Set exception on the continuation, to be rethrown
by the caller.
CONT_SET_EXC_AND_RET: Convenience which returns immediately
after setting the exception.
Implements: LockSet, SerializedAsynchronousContinuation,
LockerAndInvoker, LockerAndInvokerBase, Qutex.
Very big leap in functionality here. See qutexes.md for
an explanation of what we've done.
Async: Use new [Non]PostedAsyncCont and callOriginalCb
This new hierarchy of classes gives us a central mechanism for
managing both reply-posting and lockSpec unlocking.
* callOriginalCb: Now uses a modern C++ variadic template design
enabling it to handle both direct calling and std::bind()
re-binding of an arbitrary number of arguments from the caller.
This enables us to mostly eliminate the repeated, bespoke
definitions of callOriginalCb littered throughout the codebase.
We've also propagated these changes throughout the codebase in
this patch.
This class allows us to list a series of spinlocks that are all
acquired and released together. It has simple, primitive detection
for deadlocks and will throw if it detects one.
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.