Bug 1372670 - part 5 - add nsIThreadManager::spinEventLoopUntilEmpty; r=erahm,florian

A number of places in JS need to drain the current thread's event queue,
which cannot be done with nsIThreadManager::spinEventLoopUntil, since we
need to not wait for an incoming event when attempting to process one.
This commit is contained in:
Nathan Froyd 2017-06-21 12:59:28 -04:00
Родитель 452dc60022
Коммит b28fcc5c4b
11 изменённых файлов: 34 добавлений и 44 удалений

Просмотреть файл

@ -5177,11 +5177,7 @@ function server(port, basePath)
gThreadManager.spinEventLoopUntil(() => srv.isStopped());
var thread = gThreadManager.currentThread;
// get rid of any pending requests
while (thread.hasPendingEvents())
thread.processNextEvent(true);
gThreadManager.spinEventLoopUntilEmpty();
DEBUG = false;
}

Просмотреть файл

@ -5177,11 +5177,7 @@ function server(port, basePath)
gThreadManager.spinEventLoopUntil(() => srv.isStopped());
var thread = gThreadManager.currentThread;
// get rid of any pending requests
while (thread.hasPendingEvents())
thread.processNextEvent(true);
gThreadManager.spinEventLoopUntilEmpty();
DEBUG = false;
}

Просмотреть файл

@ -5178,11 +5178,7 @@ function server(port, basePath)
gThreadManager.spinEventLoopUntil(() => srv.isStopped());
var thread = gThreadManager.currentThread;
// get rid of any pending requests
while (thread.hasPendingEvents())
thread.processNextEvent(true);
gThreadManager.spinEventLoopUntilEmpty();
DEBUG = false;
}

Просмотреть файл

@ -5177,11 +5177,7 @@ function server(port, basePath)
gThreadManager.spinEventLoopUntil(() => srv.isStopped());
var thread = gThreadManager.currentThread;
// get rid of any pending requests
while (thread.hasPendingEvents())
thread.processNextEvent(true);
gThreadManager.spinEventLoopUntilEmpty();
DEBUG = false;
}

Просмотреть файл

@ -5178,11 +5178,7 @@ function server(port, basePath)
gThreadManager.spinEventLoopUntil(() => srv.isStopped());
var thread = gThreadManager.currentThread;
// get rid of any pending requests
while (thread.hasPendingEvents())
thread.processNextEvent(true);
gThreadManager.spinEventLoopUntilEmpty();
DEBUG = false;
}

Просмотреть файл

@ -46,12 +46,9 @@ function* testSteps()
if (this.window) {
// Make sure the success event isn't queued somehow.
let comp = SpecialPowers.wrap(Components);
let thread = comp.classes["@mozilla.org/thread-manager;1"]
.getService(comp.interfaces.nsIThreadManager)
.currentThread;
while (thread.hasPendingEvents()) {
thread.processNextEvent(false);
}
let tm = comp.classes["@mozilla.org/thread-manager;1"]
.getService(comp.interfaces.nsIThreadManager);
tm.spinEventLoopUntilEmpty();
}
finishTest();

Просмотреть файл

@ -5343,11 +5343,7 @@ function server(port, basePath)
gThreadManager.spinEventLoopUntil(() => srv.isStopped());
var thread = gThreadManager.currentThread;
// get rid of any pending requests
while (thread.hasPendingEvents())
thread.processNextEvent(true);
gThreadManager.spinEventLoopUntilEmpty();
DEBUG = false;
}

Просмотреть файл

@ -216,12 +216,10 @@ function _do_main() {
_testLogger.info("running event loop");
var tm = Components.classes["@mozilla.org/thread-manager;1"].getService();
var thr = tm.currentThread;
tm.spinEventLoopUntil(() => _quit);
while (thr.hasPendingEvents())
thr.processNextEvent(true);
tm.spinEventLoopUntilEmpty();
}
function _do_quit() {

Просмотреть файл

@ -2,8 +2,8 @@ function run_test() {
set_process_running_environment();
var file = get_test_program("TestQuickReturn");
var thread = Components.classes["@mozilla.org/thread-manager;1"]
.getService().currentThread;
var tm = Components.classes["@mozilla.org/thread-manager;1"]
.getService();
for (var i = 0; i < 1000; i++) {
var process = Components.classes["@mozilla.org/process/util;1"]
@ -20,8 +20,7 @@ function run_test() {
// We need to ensure that we process any events on the main thread -
// this allow threads to clean up properly and avoid out of memory
// errors during the test.
while (thread.hasPendingEvents())
thread.processNextEvent(false);
tm.spinEventLoopUntilEmpty();
}
}
}

Просмотреть файл

@ -105,6 +105,14 @@ interface nsIThreadManager : nsISupports
*/
void spinEventLoopUntil(in nsINestedEventLoopCondition condition);
/**
* Spin the current thread's event loop until there are no more pending
* events. This could be done with spinEventLoopUntil, but that would
* require access to the current thread from JavaScript, which we are
* moving away from.
*/
void spinEventLoopUntilEmpty();
/**
* This queues a runnable to the main thread's idle queue.
*

Просмотреть файл

@ -364,6 +364,18 @@ nsThreadManager::SpinEventLoopUntil(nsINestedEventLoopCondition* aCondition)
return rv;
}
NS_IMETHODIMP
nsThreadManager::SpinEventLoopUntilEmpty()
{
nsIThread* thread = NS_GetCurrentThread();
while (NS_HasPendingEvents(thread)) {
(void)NS_ProcessNextEvent(thread, false);
}
return NS_OK;
}
uint32_t
nsThreadManager::GetHighestNumberOfThreads()
{