// File: davmac314[P]dinit/src/proc-service.cc
// Function: process_service::handle_exit_status()
void process_service::handle_exit_status() noexcept
{
    bool did_exit = exit_status.did_exit();
    bool was_signalled = exit_status.was_signalled();
    auto current_state = get_state();

    if (notification_fd != -1) {
        readiness_watcher.deregister(event_loop);
        bp_sys::close(notification_fd);
        notification_fd = -1;
    }

    if (!exit_status.did_exit_clean() && current_state != service_state_t::STOPPING) {
        if (did_exit) {
            log(loglevel_t::ERROR, "Service ", get_name(), " process terminated with exit code ",
                    exit_status.get_exit_status());
        }
        else if (was_signalled) {
            log(loglevel_t::ERROR, "Service ", get_name(), " terminated due to signal ",
                    exit_status.get_signal());
        }
    }

    if (waiting_stopstart_timer) {
        process_timer.stop_timer(event_loop);
        waiting_stopstart_timer = false;
        if (current_state == service_state_t::STARTED) {
            // Must have been in smooth recovery and waiting for readiness notification.
            // Treat this the same as if we were STARTING:
            current_state = service_state_t::STARTING;
        }
    }

#if USE_UTMPX
    if (*inittab_id || *inittab_line) {
        clear_utmp_entry(inittab_id, inittab_line);
    }
#endif

    if (current_state == service_state_t::STARTING) {
        // If state is STARTING, we must be waiting for readiness notification; the process has
        // terminated before becoming ready.
        stop_reason = stopped_reason_t::FAILED;
        failed_to_start();
    }
    else if (current_state == service_state_t::STOPPING) {
        // We won't log a non-zero exit status or termination due to signal here -
        // we assume that the process died because we signalled it.
        if (waiting_stopstart_timer) {
            process_timer.stop_timer(event_loop);
        }
        if (!waiting_for_deps) {
            if (stop_pid == -1 && !waiting_for_execstat) {
                stop_issued = false; // reset for next time
                stopped();
            }
        }
        else if (get_target_state() == service_state_t::STARTED && !pinned_stopped) {
            initiate_start();
        }
    }
    else if (smooth_recovery && current_state == service_state_t::STARTED && check_restart()) {
        // unexpected termination, with smooth recovery
        doing_smooth_recovery = true;
        do_smooth_recovery();
        return;
    }
    else {
        handle_unexpected_termination();
    }
    services->process_queues();
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x30, %rsp
movq %rdi, -0x8(%rbp)
movq -0x8(%rbp), %rdi
movq %rdi, -0x20(%rbp)
addq $0x4dc, %rdi            # imm = 0x4DC
callq 0x4ed70
movq -0x20(%rbp), %rdi
andb $0x1, %al
movb %al, -0x9(%rbp)
addq $0x4dc, %rdi            # imm = 0x4DC
callq 0x4e4b0
movq -0x20(%rbp), %rdi
andb $0x1, %al
movb %al, -0xa(%rbp)
callq 0x2f0d0
movb %al, %cl
movq -0x20(%rbp), %rax
movb %cl, -0xb(%rbp)
cmpl $-0x1, 0x4e8(%rax)
je 0x500cb
movq -0x20(%rbp), %rdi
addq $0x510, %rdi            # imm = 0x510
leaq 0x58ab9(%rip), %rsi     # 0xa8b60
callq 0x17d20
movq -0x20(%rbp), %rax
movl 0x4e8(%rax), %edi
callq 0xad80
jmp 0x500bd
movq -0x20(%rbp), %rax
movl $0xffffffff, 0x4e8(%rax) # imm = 0xFFFFFFFF
movq -0x20(%rbp), %rdi
addq $0x4dc, %rdi            # imm = 0x4DC
callq 0x4e260
testb $0x1, %al
jne 0x5017f
cmpb $0x3, -0xb(%rbp)
je 0x5017f
testb $0x1, -0x9(%rbp)
je 0x50135
movq -0x20(%rbp), %rdi
callq 0x2d420
movq -0x20(%rbp), %rdi
movq %rax, -0x28(%rbp)
addq $0x4dc, %rdi            # imm = 0x4DC
callq 0x4e590
movq -0x28(%rbp), %rdx
movl %eax, -0x10(%rbp)
movl $0x3, %edi
leaq 0x288ec(%rip), %rsi     # 0x78a0f
leaq 0x28929(%rip), %rcx     # 0x78a53
leaq -0x10(%rbp), %r8
callq 0x50350
jmp 0x5017d
testb $0x1, -0xa(%rbp)
je 0x5017b
movq -0x20(%rbp), %rdi
callq 0x2d420
movq -0x20(%rbp), %rdi
movq %rax, -0x30(%rbp)
addq $0x4dc, %rdi            # imm = 0x4DC
callq 0x4e500
movq -0x30(%rbp), %rdx
movl %eax, -0x14(%rbp)
movl $0x3, %edi
leaq 0x288a4(%rip), %rsi     # 0x78a0f
leaq 0x28988(%rip), %rcx     # 0x78afa
leaq -0x14(%rbp), %r8
callq 0x50390
jmp 0x5017d
jmp 0x5017f
movq -0x20(%rbp), %rax
movb 0x4f4(%rax), %al
shrb %al
andb $0x1, %al
testb $0x1, %al
je 0x501ca
movq -0x20(%rbp), %rdi
addq $0x3b0, %rdi            # imm = 0x3B0
leaq 0x589bd(%rip), %rsi     # 0xa8b60
callq 0x529f0
movq -0x20(%rbp), %rax
movb 0x4f4(%rax), %cl
andb $-0x3, %cl
orb $0x0, %cl
movb %cl, 0x4f4(%rax)
cmpb $0x2, -0xb(%rbp)
jne 0x501c8
movb $0x1, -0xb(%rbp)
jmp 0x501ca
movq -0x20(%rbp), %rax
cmpb $0x0, 0x5c8(%rax)
jne 0x501e4
movq -0x20(%rbp), %rax
cmpb $0x0, 0x5cc(%rax)
je 0x50202
movq -0x20(%rbp), %rsi
movq %rsi, %rdi
addq $0x5c8, %rdi            # imm = 0x5C8
addq $0x5cc, %rsi            # imm = 0x5CC
callq 0x52c40
jmp 0x50200
jmp 0x50202
cmpb $0x1, -0xb(%rbp)
jne 0x50227
movq -0x20(%rbp), %rdi
movl $0x3, 0x1c4(%rdi)
xorl %esi, %esi
movl $0x1, %edx
callq 0x4cf90
jmp 0x50329
cmpb $0x3, -0xb(%rbp)
jne 0x502e0
movq -0x20(%rbp), %rax
movb 0x4f4(%rax), %al
shrb %al
andb $0x1, %al
testb $0x1, %al
je 0x5025a
movq -0x20(%rbp), %rdi
addq $0x3b0, %rdi            # imm = 0x3B0
leaq 0x5890b(%rip), %rsi     # 0xa8b60
callq 0x529f0
movq -0x20(%rbp), %rax
movl 0x10c(%rax), %eax
shrl $0x4, %eax
andl $0x1, %eax
testl $0x1, %eax
jne 0x502b0
movq -0x20(%rbp), %rax
cmpl $-0x1, 0x504(%rax)
jne 0x502ae
movq -0x20(%rbp), %rax
movl 0x10c(%rax), %eax
shrl $0x7, %eax
andl $0x1, %eax
testl $0x1, %eax
jne 0x502ae
movq -0x20(%rbp), %rdi
movb 0x500(%rdi), %al
andb $-0x3, %al
orb $0x0, %al
movb %al, 0x500(%rdi)
callq 0x4bb20
jmp 0x502de
movq -0x20(%rbp), %rdi
callq 0x52d20
cmpb $0x2, %al
jne 0x502dc
movq -0x20(%rbp), %rax
movl 0x10c(%rax), %eax
shrl %eax
andl $0x1, %eax
testl $0x1, %eax
jne 0x502dc
movq -0x20(%rbp), %rdi
callq 0x4c1e0
jmp 0x502de
jmp 0x50327
movq -0x20(%rbp), %rax
movl 0x10c(%rax), %eax
andl $0x1, %eax
testl $0x1, %eax
je 0x5031c
cmpb $0x2, -0xb(%rbp)
jne 0x5031c
movq -0x20(%rbp), %rdi
movq (%rdi), %rax
callq *0x28(%rax)
testb $0x1, %al
jne 0x5030a
jmp 0x5031c
movq -0x20(%rbp), %rdi
movb $0x1, 0x5b8(%rdi)
callq 0x54cf0
jmp 0x50339
movq -0x20(%rbp), %rdi
callq 0x56080
jmp 0x50327
jmp 0x50329
movq -0x20(%rbp), %rax
movq 0x148(%rax), %rdi
callq 0x173c0
addq $0x30, %rsp
popq %rbp
retq
movq %rax, %rdi
callq 0xfa30
nopw (%rax,%rax)