{
bool did_exit = WIFEXITED(exit_status);
bool was_signalled = WIFSIGNALED(exit_status);
+ restarting = false;
if (exit_status != 0 && service_state != service_state_t::STOPPING) {
if (did_exit) {
// we assume that the process died because we signalled it.
stopped();
}
- else if (smooth_recovery && service_state == service_state_t::STARTED && desired_state == service_state_t::STARTED) {
- // TODO if we are pinned-started then we should probably check
- // that dependencies have started before trying to re-start the
- // service process.
- if (! restart_ps_process()) {
- emergency_stop();
- services->process_queues();
- }
+ else if (smooth_recovery && service_state == service_state_t::STARTED
+ && desired_state == service_state_t::STARTED) {
+ do_smooth_recovery();
return;
}
else {
services->process_queues();
}
+void base_process_service::do_smooth_recovery() noexcept
+{
+ // TODO if we are pinned-started then we should probably check
+ // that dependencies have started before trying to re-start the
+ // service process.
+ if (! restart_ps_process()) {
+ emergency_stop();
+ services->process_queues();
+ }
+}
+
void bgproc_service::handle_exit_status(int exit_status) noexcept
{
begin:
if (exit_status != 0 && service_state != service_state_t::STOPPING) {
if (did_exit) {
- log(LogLevel::ERROR, "Service ", service_name, " process terminated with exit code ", WEXITSTATUS(exit_status));
+ log(LogLevel::ERROR, "Service ", service_name, " process terminated with exit code ",
+ WEXITSTATUS(exit_status));
}
else if (was_signalled) {
- log(LogLevel::ERROR, "Service ", service_name, " terminated due to signal ", WTERMSIG(exit_status));
+ log(LogLevel::ERROR, "Service ", service_name, " terminated due to signal ",
+ WTERMSIG(exit_status));
}
}
- if (doing_recovery) {
- doing_recovery = false;
+ // This may be a "smooth recovery" where we are restarting the process while leaving the
+ // service in the STARTED state.
+ if (restarting && service_state == service_state_t::STARTED) {
+ restarting = false;
bool need_stop = false;
if ((did_exit && WEXITSTATUS(exit_status) != 0) || was_signalled) {
need_stop = true;
return;
}
+ restarting = false;
if (service_state == service_state_t::STARTING) {
// POSIX requires that if the process exited clearly with a status code of 0,
// the exit status value will be 0:
stopped();
}
else if (smooth_recovery && service_state == service_state_t::STARTED && desired_state == service_state_t::STARTED) {
- // TODO if we are pinned-started then we should probably check
- // that dependencies have started before trying to re-start the
- // service process.
- doing_recovery = true;
- if (! restart_ps_process()) {
- emergency_stop();
- services->process_queues();
- }
+ do_smooth_recovery();
return;
}
else {
void base_process_service::do_restart() noexcept
{
- restarting = false;
waiting_restart_timer = false;
restart_interval_count++;
? onstart_flags.starts_on_console : onstart_flags.runs_on_console;
if (! start_ps_process(exec_arg_parts, on_console)) {
+ restarting = false;
if (service_state == service_state_t::STARTING) {
failed_to_start();
}
// rate-limited.
bool restart_ps_process() noexcept;
+ // Perform smooth recovery process
+ void do_smooth_recovery() noexcept;
+
virtual void all_deps_stopped() noexcept override;
virtual void handle_exit_status(int exit_status) noexcept = 0;
{
virtual void handle_exit_status(int exit_status) noexcept override;
- bool doing_recovery : 1; // if we are currently recovering a BGPROCESS (restarting process, while
- // holding STARTED service state)
-
enum class pid_result_t {
OK,
FAILED, // failed to read pid or read invalid pid
: base_process_service(sset, name, service_type::BGPROCESS, std::move(command), command_offsets,
std::move(pdepends_on), pdepends_soft)
{
- doing_recovery = false;
tracking_child = false;
reserved_child_watch = false;
}