Fix potential issue of double-queueing for console breakage.
authorDavin McCall <davmac@davmac.org>
Mon, 12 Jun 2017 18:00:04 +0000 (19:00 +0100)
committerDavin McCall <davmac@davmac.org>
Mon, 12 Jun 2017 18:00:04 +0000 (19:00 +0100)
src/service.cc
src/service.h

index b39fd10fec37e9e7390c5f7fe9ff6d9ba5a798a3..d1d5160d27a636e229103a5c1e372a0542fd86ea 100644 (file)
@@ -72,7 +72,7 @@ void ServiceRecord::stopped() noexcept
     if (onstart_flags.runs_on_console) {
         tcsetpgrp(0, getpgrp());
         discard_console_log_buffer();
-        releaseConsole();
+        release_console();
     }
 
     force_stop = false;
@@ -628,7 +628,7 @@ void ServiceRecord::allDepsStarted(bool has_console) noexcept
 {
     if (onstart_flags.starts_on_console && ! has_console) {
         waiting_for_deps = true;
-        queueForConsole();
+        queue_for_console();
         return;
     }
     
@@ -648,14 +648,14 @@ void ServiceRecord::acquiredConsole() noexcept
 {
     if (service_state != ServiceState::STARTING) {
         // We got the console but no longer want it.
-        releaseConsole();
+        release_console();
     }
     else if (startCheckDependencies(false)) {
         allDepsStarted(true);
     }
     else {
         // We got the console but can't use it yet.
-        releaseConsole();
+        release_console();
     }
 }
 
@@ -692,7 +692,7 @@ void ServiceRecord::started() noexcept
 {
     if (onstart_flags.starts_on_console && ! onstart_flags.runs_on_console) {
         tcsetpgrp(0, getpgrp());
-        releaseConsole();
+        release_console();
     }
 
     logServiceStarted(service_name);
@@ -725,7 +725,7 @@ void ServiceRecord::failed_to_start(bool depfailed) noexcept
 {
     if (!depfailed && onstart_flags.starts_on_console) {
         tcsetpgrp(0, getpgrp());
-        releaseConsole();
+        release_console();
     }
     
     logServiceFailed(service_name);
@@ -1158,12 +1158,12 @@ void ServiceRecord::unpin() noexcept
     }
 }
 
-void ServiceRecord::queueForConsole() noexcept
+void ServiceRecord::queue_for_console() noexcept
 {
     service_set->append_console_queue(this);
 }
 
-void ServiceRecord::releaseConsole() noexcept
+void ServiceRecord::release_console() noexcept
 {
     service_set->pullConsoleQueue();
 }
index 4ba8ab34bee395d00bd2003170c094703684082d..2a9774aa0b6fc7f41c49c7784333311fd0269bf4 100644 (file)
@@ -408,10 +408,11 @@ class ServiceRecord
     }
     
     // Queue to run on the console. 'acquiredConsole()' will be called when the console is available.
-    void queueForConsole() noexcept;
+    // Has no effect if the service has already queued for console.
+    void queue_for_console() noexcept;
     
     // Release console (console must be currently held by this service)
-    void releaseConsole() noexcept;
+    void release_console() noexcept;
     
     bool do_auto_restart() noexcept;
 
@@ -870,11 +871,11 @@ class ServiceSet
     }
     
     // Set the console queue tail (returns previous tail)
-    ServiceRecord * append_console_queue(ServiceRecord * newTail) noexcept
+    void append_console_queue(ServiceRecord * newTail) noexcept
     {
-        auto prev_tail = console_queue.tail();
-        console_queue.append(newTail);
-        return prev_tail;
+        if (! console_queue.is_queued(newTail)) {
+            console_queue.append(newTail);
+        }
     }
     
     // Retrieve the current console queue head and remove it from the queue