Allow service start to be interrupted when waiting for restart timer.
authorDavin McCall <davmac@davmac.org>
Tue, 6 Jun 2017 16:16:39 +0000 (17:16 +0100)
committerDavin McCall <davmac@davmac.org>
Tue, 6 Jun 2017 16:16:39 +0000 (17:16 +0100)
src/service.cc
src/service.h

index 96854978e956b659a4d2ffd4b92b2990f983e0f8..8595a3329efb6ab2b7d1fe38023d349c6726ce90 100644 (file)
@@ -1200,6 +1200,7 @@ base_process_service::base_process_service(ServiceSet *sset, string name, Servic
 void base_process_service::do_restart() noexcept
 {
     restarting = false;
+    waiting_restart_timer = false;
 
     // We may be STARTING (regular restart) or STARTED ("smooth recovery"). This affects whether
     // the process should be granted access to the console:
@@ -1269,10 +1270,20 @@ bool base_process_service::restart_ps_process() noexcept
     else {
         timespec timeout = diff_time(restart_delay, tdiff);
         restart_timer.arm_timer_rel(eventLoop, timeout);
+        waiting_restart_timer = true;
     }
     return true;
 }
 
+void base_process_service::interrupt_start() noexcept
+{
+    // overridden in subclasses
+    if (waiting_restart_timer) {
+        restart_timer.stop_timer(eventLoop);
+        waiting_restart_timer = false;
+    }
+}
+
 dasynq::rearm process_restart_timer::timer_expiry(EventLoop_t &, int expiry_count)
 {
     service->do_restart();
index 852eb323791673a29cce209d7a64af16784adb1c..07f524853f3df1895e3579a53d4d129e0782ed5b 100644 (file)
@@ -343,11 +343,16 @@ class ServiceRecord
 
     // Whether a STARTING service can immediately transition to STOPPED (as opposed to
     // having to wait for it reach STARTED and then go through STOPPING).
-    bool can_interrupt_start() noexcept
+    virtual bool can_interrupt_start() noexcept
     {
         return waiting_for_deps;
     }
     
+    virtual void interrupt_start() noexcept
+    {
+        // overridden in subclasses
+    }
+
     // Whether a STOPPING service can immediately transition to STARTED.
     bool can_interrupt_stop() noexcept
     {
@@ -594,17 +599,26 @@ class base_process_service : public ServiceRecord
     int max_restart_interval_count;
     timespec restart_delay;
 
+    bool waiting_restart_timer = false;
+
     // Start the process, return true on success
-    virtual bool start_ps_process() noexcept;
+    virtual bool start_ps_process() noexcept override;
     bool start_ps_process(const std::vector<const char *> &args, bool on_console) noexcept;
 
     // Restart the process (due to start failure or unexpected termination). Restarts will be
     // rate-limited.
     bool restart_ps_process() noexcept;
 
-    virtual void all_deps_stopped() noexcept;
+    virtual void all_deps_stopped() noexcept override;
     virtual void handle_exit_status(int exit_status) noexcept = 0;
 
+    virtual bool can_interrupt_start() noexcept override
+    {
+        return waiting_restart_timer || ServiceRecord::can_interrupt_start();
+    }
+
+    virtual void interrupt_start() noexcept override;
+
     public:
     base_process_service(ServiceSet *sset, string name, ServiceType service_type, string &&command,
             std::list<std::pair<unsigned,unsigned>> &command_offsets,
@@ -614,13 +628,13 @@ class base_process_service : public ServiceRecord
     {
     }
 
-    void set_restart_interval(timespec interval, int max_restarts)
+    void set_restart_interval(timespec interval, int max_restarts) noexcept
     {
         restart_interval = interval;
         max_restart_interval_count = max_restarts;
     }
 
-    void set_restart_delay(timespec delay)
+    void set_restart_delay(timespec delay) noexcept
     {
         restart_delay = delay;
     }