Bug 1498697 - stop polling when there's nothing to poll, restart when processes are re-added, r=kmag
authorGijs Kruitbosch <gijskruitbosch@gmail.com>
Tue, 30 Oct 2018 19:34:22 +0000
changeset 443634 70fd3d40a4846b76a9978d9c50aa9726bcbefe10
parent 443633 ab3a9b394d9215037d55b40a6d709d6c40a46598
child 443635 858eaf4e3f0044a5ee9f79dee8b3a0a57a0c3963
push id109420
push useraciure@mozilla.com
push dateWed, 31 Oct 2018 05:11:56 +0000
treeherdermozilla-inbound@b357da105c49 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskmag
bugs1498697
milestone65.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1498697 - stop polling when there's nothing to poll, restart when processes are re-added, r=kmag Differential Revision: https://phabricator.services.mozilla.com/D8962
toolkit/modules/subprocess/subprocess_worker_unix.js
toolkit/modules/subprocess/subprocess_worker_win.js
--- a/toolkit/modules/subprocess/subprocess_worker_unix.js
+++ b/toolkit/modules/subprocess/subprocess_worker_unix.js
@@ -494,16 +494,18 @@ io = {
   pipes: new Map(),
 
   processes: new Map(),
 
   messageCount: 0,
 
   running: true,
 
+  polling: false,
+
   init(details) {
     this.signal = new Signal(details.signalFd);
     this.updatePollFds();
 
     setTimeout(this.loop.bind(this), 0);
   },
 
   shutdown() {
@@ -540,33 +542,43 @@ io = {
 
   updatePollFds() {
     let handlers = [this.signal,
                     ...this.pipes.values(),
                     ...this.processes.values()];
 
     handlers = handlers.filter(handler => handler.pollEvents);
 
+    // Our poll loop is only useful if we've got at least 1 thing to poll other than our own
+    // signal.
+    if (handlers.length == 1) {
+      this.polling = false;
+    } else if (!this.polling && this.running) {
+      // Restart the poll loop if necessary:
+      setTimeout(this.loop.bind(this), 0);
+      this.polling = true;
+    }
+
     let pollfds = unix.pollfd.array(handlers.length)();
 
     for (let [i, handler] of handlers.entries()) {
       let pollfd = pollfds[i];
 
       pollfd.fd = handler.fd;
       pollfd.events = handler.pollEvents;
       pollfd.revents = 0;
     }
 
     this.pollFds = pollfds;
     this.pollHandlers = handlers;
   },
 
   loop() {
     this.poll();
-    if (this.running) {
+    if (this.running && this.polling) {
       setTimeout(this.loop.bind(this), 0);
     }
   },
 
   poll() {
     let handlers = this.pollHandlers;
     let pollfds = this.pollFds;
 
--- a/toolkit/modules/subprocess/subprocess_worker_win.js
+++ b/toolkit/modules/subprocess/subprocess_worker_win.js
@@ -611,16 +611,18 @@ io = {
   pipes: new Map(),
 
   processes: new Map(),
 
   messageCount: 0,
 
   running: true,
 
+  polling: false,
+
   init(details) {
     this.comspec = details.comspec;
 
     let signalEvent = ctypes.cast(ctypes.uintptr_t(details.signalEvent),
                                   win32.HANDLE);
     this.signal = new Signal(signalEvent);
     this.updatePollEvents();
 
@@ -663,25 +665,35 @@ io = {
 
   updatePollEvents() {
     let handlers = [this.signal,
                     ...this.pipes.values(),
                     ...this.processes.values()];
 
     handlers = handlers.filter(handler => handler.event);
 
+    // Our poll loop is only useful if we've got at least 1 thing to poll other than our own
+    // signal.
+    if (handlers.length == 1) {
+      this.polling = false;
+    } else if (!this.polling && this.running) {
+      // Restart the poll loop if necessary:
+      setTimeout(this.loop.bind(this), 0);
+      this.polling = true;
+    }
+
     this.eventHandlers = handlers;
 
     let handles = handlers.map(handler => handler.event);
     this.events = win32.HANDLE.array()(handles);
   },
 
   loop() {
     this.poll();
-    if (this.running) {
+    if (this.running && this.polling) {
       setTimeout(this.loop.bind(this), 0);
     }
   },
 
 
   poll() {
     let timeout = this.messageCount > 0 ? 0 : POLL_TIMEOUT;
     for (;; timeout = 0) {