// File: /workspace/github_cpp_makefile_star2_O2/davmac314[P]dinit/src/service.cc
// Function: service_record::stopped()
void service_record::stopped() noexcept
{
    if (have_console) {
        bp_sys::tcsetpgrp(0, bp_sys::getpgrp());
        release_console();
    }

    force_stop = false;

    // If we are to re-start, restarting should have been set true and desired_state should be STARTED.
    // (A restart could be cancelled via a separately issued stop, including via a shutdown).
    bool will_restart = desired_state == service_state_t::STARTED && !pinned_stopped;

    // If we won't restart, break soft dependencies now
    if (!will_restart) {
        for (auto dept : dependents) {
            if (!dept->is_hard()) {
                // waits-for or soft dependency:
                if (dept->waiting_on) {
                    dept->waiting_on = false;
                    dept->get_from()->dependency_started();
                }
                if (dept->holding_acq) {
                    dept->holding_acq = false;
                    // release without issuing stop, since we're called only when this
                    // service is already stopped/stopping:
                    release(false);
                }
            }
        }
    }

    for (auto & dependency : depends_on) {
        // we signal dependencies in case they are waiting for us to stop:
        dependency.get_to()->dependent_stopped();
    }

    service_state = service_state_t::STOPPED;

    if (will_restart) {
        // Desired state is "started".
        initiate_start();
    }
    else {
        becoming_inactive();

        if (start_explicit) {
            // If we were explicitly started, our required_by count must be at least 1. Use
            // release() to correctly release, mark inactive and release dependencies.
            start_explicit = false;
            release(false);
        }
        else if (required_by == 0) {
            // This can only be the case if we didn't have start_explicit, since required_by would
            // otherwise by non-zero. Since our release(s) above were with state != STOPPED, we now
            // must mark inactive (i.e. it won't have been done as part of the release).
            services->service_inactive(this);
        }
    }

    // Start failure will have been logged already, only log if we are stopped for other reasons:
    if (!start_failed) {
        log_service_stopped(service_name);

        // If this service chains to another, start the chained service now, if:
        // - this service self-terminated (rather than being stopped),
        // - ... successfully (i.e. exit code 0)
        // - this service won't restart, and
        // - a shutdown isn't in progress
        if ((onstart_flags.always_chain || (did_finish(stop_reason)
                && get_exit_status().did_exit_clean() && !will_restart))
                && !start_on_completion.empty() && !services->is_shutting_down()) {
            try {
                auto chain_to = services->load_service(start_on_completion.c_str());
                chain_to->start();
            }
            catch (service_load_exc &sle) {
                log(loglevel_t::ERROR, "Couldn't chain to service ", start_on_completion, ": ",
                        "couldn't load ", sle.service_name, ": ", sle.exc_description);
            }
            catch (std::bad_alloc &bae) {
                log(loglevel_t::ERROR, "Couldn't chain to service ", start_on_completion,
                        ": Out of memory");
            }
        }
    }
    notify_listeners(service_event_t::STOPPED);
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
movq %rdi, %rbx
movl 0x10c(%rdi), %eax
testb $0x40, %al
je 0x1e33b
callq 0x8180
xorl %edi, %edi
movl %eax, %esi
callq 0x88b0
movq %rbx, %rdi
callq 0x1e53a
movl 0x10c(%rbx), %eax
movb $0x0, 0x190(%rbx)
cmpb $0x2, 0x2d(%rbx)
sete %cl
testb $0x2, %al
sete %bpl
andb %cl, %bpl
je 0x1e387
leaq 0x118(%rbx), %r14
movq %r14, %r15
movq (%r15), %r15
cmpq %r14, %r15
je 0x1e371
movq 0x18(%r15), %rdi
callq 0x1e646
jmp 0x1e35e
movb $0x0, 0x2c(%rbx)
testb %bpl, %bpl
je 0x1e3e8
movq %rbx, %rdi
callq 0x1e684
jmp 0x1e427
leaq 0x130(%rbx), %r14
movq %r14, %r15
movq (%r15), %r15
cmpq %r14, %r15
je 0x1e354
movq 0x10(%r15), %r12
movl 0x14(%r12), %eax
testl %eax, %eax
je 0x1e391
cmpl $0x3, %eax
jne 0x1e3b6
movb 0x10(%r12), %al
testb %al, %al
jne 0x1e391
jmp 0x1e3bb
movb 0x10(%r12), %al
testb $0x1, %al
je 0x1e3ce
movb $0x0, 0x10(%r12)
movq (%r12), %rdi
callq 0x1e54e
cmpb $0x1, 0x11(%r12)
jne 0x1e391
movb $0x0, 0x11(%r12)
movq %rbx, %rdi
xorl %esi, %esi
callq 0x1e58e
jmp 0x1e391
movq (%rbx), %rax
movq %rbx, %rdi
callq *0x20(%rax)
movl 0x10c(%rbx), %eax
btl $0x8, %eax
jb 0x1e412
cmpl $0x0, 0x110(%rbx)
jne 0x1e427
movq 0x148(%rbx), %rax
decl 0x8(%rax)
jmp 0x1e427
andl $0xfffffeff, %eax       # imm = 0xFFFFFEFF
movl %eax, 0x10c(%rbx)
movq %rbx, %rdi
xorl %esi, %esi
callq 0x1e58e
testb $-0x80, 0x10d(%rbx)
jne 0x1e48c
movq 0x8(%rbx), %rdi
callq 0x2909c
testb $0x4, 0x2f(%rbx)
jne 0x1e45d
cmpl $0x6, 0x1c4(%rbx)
jne 0x1e48c
movq (%rbx), %rax
movq %rbx, %rdi
callq *0x50(%rax)
shrq $0x20, %rax
setne %al
orb %al, %bpl
jne 0x1e48c
cmpq $0x0, 0x1d0(%rbx)
je 0x1e48c
movq 0x148(%rbx), %rdi
cmpb $0x1, 0x28(%rdi)
jne 0x1e48c
leaq 0x1c8(%rbx), %r14
movq (%r14), %rsi
movq (%rdi), %rax
callq *0x10(%rax)
movq %rax, %rdi
callq 0x1e6dc
pushq $0x1
popq %rsi
movq %rbx, %rdi
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
jmp 0x1f59e
cmpl $0x3, %edx
jne 0x1e4f7
movq %rax, %rdi
callq 0x8200
movq %rax, %r15
leaq 0x114fb(%rip), %rsi     # 0x2f9b1
pushq $0x3
popq %rdi
callq 0x28e0a
movq %r14, %rdi
callq 0x1f57e
leaq 0xf734(%rip), %r14      # 0x2dc01
movq %r14, %rdi
callq 0x28f17
leaq 0x11500(%rip), %rdi     # 0x2f9dc
callq 0x28f17
movq %r15, %rdi
callq 0x1f57e
movq %r14, %rdi
callq 0x28f17
movq 0x20(%r15), %rdi
jmp 0x1e522
cmpl $0x2, %edx
jne 0x1e531
movq %rax, %rdi
callq 0x8200
leaq 0x114a6(%rip), %rsi     # 0x2f9b1
pushq $0x3
popq %rdi
callq 0x28e0a
movq %r14, %rdi
callq 0x1f57e
leaq 0x114aa(%rip), %rdi     # 0x2f9cc
callq 0x28f31
callq 0x8a40
jmp 0x1e48c
movq %rax, %rdi
callq 0xaebb
nop