https://code.google.com/p/singularity-viewer/issues/detail?id=848
If advance_state is called, then the state is NOT changed (only
sub_state_w->advance_state is set), but sub_state_w->skip_idle is set to
true in order to ignore the next call to idle (if the state machine is
already in the middle of executing a state). Therefore, this assert
would trigger. The solution is to not trigger when skip_idle is set.
When a state machine is aborted after it switched to bs_initialize,
but before it executed initialize_impl(), then we should set the
state back to bs_reset and abort cleanly by switching to bs_killed
and then handle that. Before the state was set to bs_abort, resulting
in calling abort_impl(), finish_impl(), the call back and unref()
for an not initialized state machine! (detected by the assert that
makes sure that ref()/unref() are called in balance).
The responder name is now cached in LLURLRequest
(ResponderBase::getName() must return a string literal).
The run time (in the main thread) per state machine is now accumulated
in AIStateMachine (instead of AIEngine::QueueElement).
When AIStateMachine::mainloop runs longer than StateMachineMaxTime
then a warning is printed that now includes the time spent in the
slowest state machine (that frame) and (if it is a LLURLRequest)
what the corresponding responder is. Also the total accumulated run
time of that state machine is printed.
From this is can be concluded that the only responder currently
regularly holding up the main thread is LLMeshLODResponder (mostly 30 to
100 ms, but with spikes in the 1 to 2 second range some times).
This fixes a bug where unref() was called when a state machine was
aborted before it reached bs_initialized. Debug code was added to detect
errors related to that.
In order to run HTTPGetResponder in any thread, I needed direct access
to LLHTTPClient::request, so I had to move that to the header file,
and therefore had to move ERequestAction from LLURLRequest to
LLHTTPClient to avoid include problems.
With this, textures are fetched with no latency: call to
LLHTTPClient::request runs all the way till the state machine is idle
(AICurlEasyRequestStateMachine_waitAdded). There is small delay till the
curl thread wakes up, which then processes the request and opens the url
etc. When the transaction is finished, it calls
AIStateMachine::advance_state(AICurlEasyRequestStateMachine_removed_after_finished)
which subsequently doesn't return until the state machine is completely
finished (bs_killed). The LLURLRequest isn't deleted yet at that point
because the AITimer of the LLURLRequest runs in the main thread: it is
aborted, but only the next time the main thread state engines run that
is deleted and the timer keeps an LLPointer to it's parent, the
LLURLRequest, so only then the LLURLRequest object is destructed. This
however has nothing to do with the texture-bandwidth loop.
This reverts commit ef35aa7954
because it contained too much wrong things that I won't be
using. I'll re-commit stuff from it after that that I do
want to keep.
This work extends AIStateMachine to run multiplex() in the thread
that calls run(), cont() or set_state(). Note that all three
eventually call locked_cont(), so thats where multiplex() is called
from. Calling multiplex() means "running the state machine", as in
"calling multiplex_impl".
Currently only LLURLRequest uses this feature, and then only
for the HTTPGetResponder, and well only for the initializing,
start up and normal finish states.
A current/remaining problem is that we run into a situation where
the curl thread runs a statemachine to it's finish and kills it,
while the main thread is also 'running' it and tries to call
multiplex while the statemachine isn't running anymore.
As idle statemachines aren't in any list, it's not possible
(without adding that list) to delete them. I don't think
that there are any active statemachines left at the end
of flush anyway, but killing them doesn't much sense if
we can't get them all: there will always be statemachines
left: those that were idle at the moment the viewer was
quit.
Since we changed CurlResponderBuffer to be derived from CurlEasyRequest
and therefore changed it's name to BufferedCurlEasyRequest, we should
also rename AICurlResponderBufferEvents to
AIBufferedCurlEasyRequestEvents.
This commit also fixes C++ comment in several places to reflex the
previous name change.