Age | Commit message (Collapse) | Author |
|
Reverting a merge is sticky: it tells git you never want to see that branch
again. Merging the DRTVWR-546 branch, which contained the revert, into the
glthread branch undid much of the development work on that branch. To restore
it we must revert the revert.
This reverts commit 029b41c0419e975bbb28454538b46dc69ce5d2ba.
|
|
|
|
|
|
This reverts commit 5188a26a8521251dda07ac0140bb129f28417e49, reversing
changes made to 819088563e13f1d75e048311fbaf0df4a79b7e19.
|
|
We want to skip calling PostMessage() to bump the window thread out of
GetMessage() in any frame with no work functions pending for that thread. That
test depends on being able to sense the size() of the queue. Having converted
to WorkQueue, we need that queue to support size().
|
|
Give ThreadPool and WorkQueue the ability to override default
ThreadSafeSchedule capacity.
Instantiate "mainloop" WorkQueue and "General" ThreadPool with very large
capacity because we never want to have to block trying to push to either.
|
|
postIfOpen() provides a no-exception alternative to post(), which blocks if
full but throws if closed. postIfOpen() likewise blocks if full, but returns
true if able to post and false if the queue was closed.
|
|
|
|
|
|
|
|
postTo() sets up two-way communication: the caller asks to run work on some
other WorkQueue, expecting an eventual callback on the originating WorkQueue.
That permits us to transport any exception thrown by the work callable back to
rethrow on the originating WorkQueue.
|
|
In addition to the name making the blocking explicit, we changed the
signature: instead of specifying a target WorkQueue on which to run,
waitForResult() runs the passed callable on its own WorkQueue.
Why is that? Because, unlike postTo(), we do not require a handshake between
two different WorkQueues. postTo() allows running arbitrary callback code,
setting variables or whatever, on the originating WorkQueue (presumably on the
originating thread). waitForResult() synchronizes using Promise/Future, which
are explicitly designed for cross-thread communication. We need not call
set_value() on the originating thread, so we don't need a postTo() callback
lambda.
|
|
The idea is that you can call runOn(target, callable) from a (non-default)
coroutine and block that coroutine until the result becomes available.
As a safety check, we forbid calling runOn() from a thread's default
coroutine, assuming that a given thread's default coroutine is the one
servicing the relevant WorkQueue.
|
|
Add a test exercising this feature.
|
|
ThreadPool bundles a WorkQueue with the specified number of worker threads to
service it. Each ThreadPool has a name that can be used to locate its
WorkQueue.
Each worker thread calls WorkQueue::runUntilClose().
ThreadPool listens on the "LLApp" LLEventPump for shutdown notification. On
receiving that, it closes its WorkQueue and then join()s each of its worker
threads for orderly shutdown.
Add a settings.xml entry "ThreadPoolSizes", the first LLSD-valued settings
entry to expect a map: pool name->size. The expectation is that usually code
instantiating a particular ThreadPool will have a default size in mind, but it
should check "ThreadPoolSizes" for a user override.
Make idle_startup()'s STATE_SEED_CAP_GRANTED state instantiate a "General"
ThreadPool. This is function-static for lazy initialization.
Eliminate LLMainLoopRepeater, which is completely unreferenced. Any potential
future use cases are better addressed by posting to the main loop's WorkQueue.
Eliminate llappviewer.cpp's private LLDeferredTaskList class, which
implemented LLAppViewer::addOnIdleCallback(). Make addOnIdleCallback() post
work to the main loop's WorkQueue instead.
|
|
It seems CALLBACK is a macro in some Microsoft header file. Bleah.
|
|
A typical WorkQueue has a string name, which can be used to find it to post
work to it. "Work" is a nullary callable.
WorkQueue is a multi-producer, multi-consumer thread-safe queue: multiple
threads can service the WorkQueue, multiple threads can post work to it.
Work can be scheduled in the future by submitting with a timestamp. In
addition, a given work item can be scheduled to run on a recurring basis.
A requesting thread servicing a WorkQueue of its own, such as the viewer's
main thread, can submit work to another WorkQueue along with a callback to be
passed the result (of arbitrary type) of the first work item. The callback is
posted to the originating WorkQueue, permitting safe data exchange between
participating threads.
Methods are provided for different kinds of servicing threads. runUntilClose()
is useful for a simple worker thread. runFor(duration) devotes no more than a
specified time slice to that WorkQueue, e.g. for use by the main thread.
|