// File: /workspace/github_cpp_makefile_star2_O2/davmac314[P]dinit/src/service.cc
// Function: service_record::do_stop(bool)
void service_record::do_stop(bool with_restart) noexcept
{
    // Called when we should definitely stop. We may need to restart afterwards, but we
    // won't know that for sure until the execution transition.
    // Note: to inhibit automatic restart, including restart due to dependent still requiring this
    //       service, caller must first set desired_state to STOPPED

    if (is_start_pinned()) return;

    in_auto_restart = false;
    in_user_restart = false;

    // Will we restart? desired state of STOPPED inhibits auto-restart
    bool do_auto_restart = false;
    if (auto_restart == auto_restart_mode::ALWAYS) {
        do_auto_restart = true;
    }
    else if (auto_restart == auto_restart_mode::ON_FAILURE) {
        if (get_type() == service_type_t::PROCESS || get_type() == service_type_t::BGPROCESS) {
            auto exit_status = get_exit_status();
            if (exit_status.was_signalled()) {
                if (!value(exit_status.get_signal()).is_in(SIGHUP, SIGINT, SIGUSR1, SIGUSR2, SIGTERM)) {
                    do_auto_restart = true;
                }
            }
            else {
                if (exit_status.get_exit_status() != 0) {
                    do_auto_restart = true;
                }
            }
        }
    }
    bool for_restart = with_restart || (do_auto_restart && desired_state == service_state_t::STARTED);
    bool restart_deps = with_restart;

    if (!with_restart && for_restart) {
        // auto restart - check for restarting too often
        for_restart = check_restart();
        in_auto_restart = for_restart;
    }

    // If we won't restart, release explicit activation:
    if (!for_restart) {
        if (start_explicit) {
            start_explicit = false;
            release(false);
        }
    }

    bool all_deps_stopped = stop_dependents(for_restart, restart_deps);

    if (service_state != service_state_t::STARTED) {
        if (service_state == service_state_t::STARTING) {
            // If waiting for a dependency, or waiting for the console, we can interrupt start. Otherwise,
            // we need to delegate to can_interrupt_start() (which can be overridden).
            if (!waiting_for_deps && !waiting_for_console) {
                if (!can_interrupt_start()) {
                    // Well this is awkward: we're going to have to continue starting. We can stop once
                    // we've reached the started state.
                    return;
                }

                if (!interrupt_start()) {
                    // Now wait for service startup to actually end; we don't need to handle it here.
                    notify_listeners(service_event_t::STARTCANCELLED);
                    return;
                }
            }
            else if (waiting_for_console) {
                services->unqueue_console(this);
                waiting_for_console = false;
            }

            // We must have had desired_state == STARTED.
            notify_listeners(service_event_t::STARTCANCELLED);

            // Reaching this point, we are starting interruptibly - so we
            // stop now (by falling through to below).
        }
        else {
            // If we're starting we need to wait for that to complete.
            // If we're already stopping/stopped there's nothing to do.
            return;
        }
    }

    service_state = service_state_t::STOPPING;
    waiting_for_deps = !all_deps_stopped;
    if (all_deps_stopped) {
        services->add_transition_queue(this);
    }
}

// Assembly:
pushq %rbp
pushq %r14
pushq %rbx
subq $0x20, %rsp
movl 0x10c(%rdi), %eax
testb $0xc, %al
je 0x1e775
addq $0x20, %rsp
popq %rbx
popq %r14
popq %rbp
retq
movl %esi, %ebp
movq %rdi, %rbx
andl $0xfff9fff3, %eax       # imm = 0xFFF9FFF3
movl %eax, 0x10c(%rdi)
movl 0x108(%rdi), %ecx
cmpl $0x1, %ecx
je 0x1e7be
movl %ebp, %eax
cmpl $0x2, %ecx
jne 0x1e7ce
movl 0x28(%rbx), %ecx
decl %ecx
movl %ebp, %eax
cmpl $0x1, %ecx
ja 0x1e7ce
movq (%rbx), %rax
movq %rbx, %rdi
callq *0x50(%rax)
cmpl $0x1, %eax
jne 0x1e90d
shrq $0x20, %rax
sete %al
jmp 0x1e7c0
xorl %eax, %eax
orb %bpl, %al
movl %ebp, %eax
jne 0x1e7ce
cmpb $0x2, 0x2d(%rbx)
sete %al
movl %eax, %ecx
notb %cl
orb %bpl, %cl
testb $0x1, %cl
je 0x1e7e9
movb $0x1, %r14b
testb %al, %al
jne 0x1e837
movl 0x10c(%rbx), %eax
jmp 0x1e814
movq (%rbx), %rax
movq %rbx, %rdi
callq *0x28(%rax)
movzbl %al, %ecx
movl %ecx, %edx
shll $0x11, %edx
movl $0xfffdffff, %eax       # imm = 0xFFFDFFFF
andl 0x10c(%rbx), %eax
orl %edx, %eax
movl %eax, 0x10c(%rbx)
movb $0x1, %r14b
testb %cl, %cl
jne 0x1e837
btl $0x8, %eax
jb 0x1e81f
xorl %r14d, %r14d
jmp 0x1e837
andl $0xfffffeff, %eax       # imm = 0xFFFFFEFF
movl %eax, 0x10c(%rbx)
xorl %r14d, %r14d
movq %rbx, %rdi
xorl %esi, %esi
callq 0x1e58e
movzbl %r14b, %esi
movzbl %bpl, %edx
movq %rbx, %rdi
callq 0x1f202
movl %eax, %ebp
movzbl 0x2c(%rbx), %eax
cmpl $0x2, %eax
je 0x1e8ae
cmpl $0x1, %eax
jne 0x1e76c
movl 0x10c(%rbx), %eax
testb $0x30, %al
je 0x1e881
testb $0x20, %al
je 0x1e8a3
movq 0x148(%rbx), %rdi
movq %rbx, %rsi
callq 0x1f5ce
andb $-0x21, 0x10c(%rbx)
jmp 0x1e8a3
movq (%rbx), %rax
movq %rbx, %rdi
callq *0x10(%rax)
testb %al, %al
je 0x1e76c
movq (%rbx), %rax
movq %rbx, %rdi
callq *0x18(%rax)
testb %al, %al
je 0x1e961
pushq $0x3
popq %rsi
movq %rbx, %rdi
callq 0x1f59e
movb $0x3, 0x2c(%rbx)
movl 0x10c(%rbx), %eax
movl %ebp, %ecx
xorb $0x1, %cl
movzbl %cl, %ecx
shll $0x4, %ecx
andl $-0x11, %eax
orl %ecx, %eax
movl %eax, 0x10c(%rbx)
testb %bpl, %bpl
je 0x1e76c
movq 0x148(%rbx), %rax
cmpq $0x0, 0x200(%rbx)
setne %dl
movq 0x40(%rax), %rcx
cmpq %rbx, %rcx
sete %sil
orb %dl, %sil
jne 0x1e76c
movq %rcx, 0x200(%rbx)
movq %rbx, 0x40(%rax)
jmp 0x1e76c
shrq $0x20, %rax
leaq 0x14(%rsp), %rcx
movl %eax, (%rcx)
leaq 0x18(%rsp), %rdi
movq %rcx, (%rdi)
leaq 0x10(%rsp), %rsi
movl $0x1, (%rsi)
leaq 0xc(%rsp), %rdx
movl $0x2, (%rdx)
leaq 0x8(%rsp), %rcx
movl $0xa, (%rcx)
leaq 0x4(%rsp), %r8
movl $0xc, (%r8)
movq %rsp, %r9
movl $0xf, (%r9)
callq 0x1f5e2
jmp 0x1e7c0
pushq $0x3
popq %rsi
movq %rbx, %rdi
callq 0x1f59e
jmp 0x1e76c
movq %rax, %rdi
callq 0xaebb
nop