// File: /workspace/github_cpp_makefile_star2_O3/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
movl 0x10c(%rdi), %eax
testb $0xc, %al
je 0x22cab
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), %eax
cmpl $0x1, %eax
je 0x22d1b
movl %ebp, %ecx
cmpl $0x2, %eax
jne 0x22d2b
movl 0x28(%rbx), %eax
decl %eax
movl %ebp, %ecx
cmpl $0x1, %eax
ja 0x22d2b
movq (%rbx), %rax
movq %rbx, %rdi
callq *0x50(%rax)
movq %rax, %rcx
shrq $0x20, %rax
cmpl $0x1, %ecx
jne 0x22cf6
testq %rax, %rax
sete %al
jmp 0x22d1d
cmpl $0xa, %eax
ja 0x22d07
movl $0x406, %ecx            # imm = 0x406
btl %eax, %ecx
movl %ebp, %ecx
jb 0x22d2b
cmpq $0xc, %rax
sete %cl
cmpq $0xf, %rax
sete %al
orb %cl, %al
movl %ebp, %ecx
jne 0x22d2b
xorl %eax, %eax
orb %bpl, %al
movl %ebp, %ecx
jne 0x22d2b
cmpb $0x2, 0x2d(%rbx)
sete %cl
movl %ecx, %eax
notb %al
orb %bpl, %al
testb $0x1, %al
je 0x22d45
movb $0x1, %r14b
testb %cl, %cl
jne 0x22d93
movl 0x10c(%rbx), %eax
jmp 0x22d70
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 0x22d93
btl $0x8, %eax
jb 0x22d7b
xorl %r14d, %r14d
jmp 0x22d93
andl $0xfffffeff, %eax       # imm = 0xFFFFFEFF
movl %eax, 0x10c(%rbx)
xorl %r14d, %r14d
movq %rbx, %rdi
xorl %esi, %esi
callq 0x22a24
movzbl %r14b, %esi
movzbl %bpl, %edx
movq %rbx, %rdi
callq 0x238a4
movl %eax, %ebp
movzbl 0x2c(%rbx), %eax
cmpl $0x2, %eax
je 0x22e73
cmpl $0x1, %eax
jne 0x22ca6
movl 0x10c(%rbx), %ecx
testb $0x30, %cl
je 0x22e2f
testb $0x20, %cl
je 0x22e51
movq 0x1e8(%rbx), %rax
testq %rax, %rax
je 0x22e24
movq 0x148(%rbx), %rdx
leaq 0x1e8(%rbx), %rcx
cmpq %rbx, 0x30(%rdx)
jne 0x22e03
xorl %esi, %esi
cmpq %rbx, %rax
cmovneq %rax, %rsi
movq %rsi, 0x30(%rdx)
movq 0x1e8(%rbx), %rax
movq 0x1f0(%rbx), %rdx
movq %rdx, 0x1f0(%rax)
movq %rax, 0x1e8(%rdx)
xorps %xmm0, %xmm0
movups %xmm0, (%rcx)
movl 0x10c(%rbx), %ecx
andl $-0x21, %ecx
movl %ecx, 0x10c(%rbx)
jmp 0x22e51
movq (%rbx), %rax
movq %rbx, %rdi
callq *0x10(%rax)
testb %al, %al
je 0x22ca6
movq (%rbx), %rax
movq %rbx, %rdi
callq *0x18(%rax)
testb %al, %al
je 0x22ed2
movq 0x160(%rbx), %r14
testq %r14, %r14
je 0x22e73
movq 0x8(%r14), %rdi
movq (%rdi), %rax
movq %rbx, %rsi
movl $0x3, %edx
callq *(%rax)
movq (%r14), %r14
jmp 0x22e58
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 0x22ca6
movq 0x148(%rbx), %rax
cmpq $0x0, 0x200(%rbx)
setne %dl
movq 0x40(%rax), %rcx
cmpq %rbx, %rcx
sete %sil
orb %dl, %sil
jne 0x22ca6
movq %rcx, 0x200(%rbx)
movq %rbx, 0x40(%rax)
jmp 0x22ca6
movq 0x160(%rbx), %r14
testq %r14, %r14
je 0x22ca6
movq 0x8(%r14), %rdi
movq (%rdi), %rax
movq %rbx, %rsi
movl $0x3, %edx
callq *(%rax)
movq (%r14), %r14
jmp 0x22ed9
movq %rax, %rdi
callq 0xb74e