// File: davmac314[P]dinit/src/control.cc
// Function: control_conn_t::process_close_handle()
bool control_conn_t::process_close_handle()
{
    constexpr int pkt_size = 1 + sizeof(handle_t);

    if (rbuf.get_length() < pkt_size) {
        chklen = pkt_size;
        return true;
    }

    handle_t handle;
    rbuf.extract((char *) &handle, 1, sizeof(handle));

    rbuf.consume(pkt_size);
    chklen = 0;

    auto key_it = key_service_map.find(handle);
    if (key_it == key_service_map.end()) {
        // Service handle is bad
        char badreq_rep[] = { (char)cp_rply::BADREQ };
        if (!queue_packet(badreq_rep, 1)) return false;
        bad_conn_close = true;
        return true;
    }

    service_record *service = key_it->second;
    key_service_map.erase(key_it);

    bool have_other_handle = false;
    auto handle_range = service_key_map.equal_range(service);
    auto it = handle_range.first;
    while (it->second != handle) {
        have_other_handle = true;
        ++it;
    }
    if (!have_other_handle) {
        // check if more handles beyond the found handle
        have_other_handle = std::next(it) != handle_range.second;
    }
    service_key_map.erase(it);

    if (!have_other_handle) {
        service->remove_listener(this);
    }

    char ack_reply[] = { (char)cp_rply::ACK };
    return queue_packet(ack_reply, sizeof(ack_reply));
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0xa0, %rsp
movq %rdi, -0x10(%rbp)
movq -0x10(%rbp), %rdi
movq %rdi, -0x98(%rbp)
movl $0x5, -0x14(%rbp)
addq $0x80, %rdi
callq 0x5e200
cmpl $0x5, %eax
jae 0x58ae9
movq -0x98(%rbp), %rax
movl $0x5, 0x7c(%rax)
movb $0x1, -0x1(%rbp)
jmp 0x58cc7
movq -0x98(%rbp), %rdi
addq $0x80, %rdi
leaq -0x18(%rbp), %rsi
movl $0x1, %edx
movl $0x4, %ecx
callq 0x5e220
movq -0x98(%rbp), %rdi
addq $0x80, %rdi
movl $0x5, %esi
callq 0x5e1a0
movq -0x98(%rbp), %rdi
movl $0x0, 0x7c(%rdi)
addq $0x4c0, %rdi            # imm = 0x4C0
leaq -0x18(%rbp), %rsi
callq 0x5e6a0
movq -0x98(%rbp), %rdi
movq %rax, -0x20(%rbp)
addq $0x4c0, %rdi            # imm = 0x4C0
callq 0x5e700
movq %rax, -0x28(%rbp)
leaq -0x20(%rbp), %rdi
leaq -0x28(%rbp), %rsi
callq 0x5e6d0
testb $0x1, %al
jne 0x58b6e
jmp 0x58bad
movq -0x98(%rbp), %rdi
movb 0x208c2(%rip), %al      # 0x7943d
movb %al, -0x29(%rbp)
leaq -0x29(%rbp), %rsi
movl $0x1, %edx
callq 0x58340
testb $0x1, %al
jne 0x58b99
movb $0x0, -0x1(%rbp)
jmp 0x58cc7
movq -0x98(%rbp), %rax
movb $0x1, 0x78(%rax)
movb $0x1, -0x1(%rbp)
jmp 0x58cc7
leaq -0x20(%rbp), %rdi
callq 0x5e730
movq -0x98(%rbp), %rdi
movq 0x8(%rax), %rax
movq %rax, -0x38(%rbp)
addq $0x4c0, %rdi            # imm = 0x4C0
movq -0x20(%rbp), %rax
movq %rax, -0x40(%rbp)
movq -0x40(%rbp), %rsi
callq 0x5e750
movq -0x98(%rbp), %rdi
movq %rax, -0x48(%rbp)
movb $0x0, -0x49(%rbp)
addq $0x488, %rdi            # imm = 0x488
leaq -0x38(%rbp), %rsi
callq 0x5e790
movq %rax, -0x60(%rbp)
movq %rdx, -0x58(%rbp)
movq -0x60(%rbp), %rax
movq %rax, -0x68(%rbp)
leaq -0x68(%rbp), %rdi
callq 0x5e7d0
movl 0x8(%rax), %eax
cmpl -0x18(%rbp), %eax
je 0x58c2c
movb $0x1, -0x49(%rbp)
leaq -0x68(%rbp), %rdi
callq 0x5e800
jmp 0x58c0c
testb $0x1, -0x49(%rbp)
jne 0x58c62
movq -0x68(%rbp), %rax
movq %rax, -0x78(%rbp)
movq -0x78(%rbp), %rdi
movl $0x1, %esi
callq 0x5e860
movq %rax, -0x70(%rbp)
leaq -0x60(%rbp), %rsi
addq $0x8, %rsi
leaq -0x70(%rbp), %rdi
callq 0x5e830
andb $0x1, %al
movb %al, -0x49(%rbp)
movq -0x98(%rbp), %rdi
addq $0x488, %rdi            # imm = 0x488
movq -0x68(%rbp), %rax
movq %rax, -0x80(%rbp)
movq -0x80(%rbp), %rsi
callq 0x5e890
movq %rax, -0x88(%rbp)
testb $0x1, -0x49(%rbp)
jne 0x58c9e
movq -0x98(%rbp), %rsi
movq -0x38(%rbp), %rdi
callq 0x5e8d0
movq -0x98(%rbp), %rdi
movb 0x20793(%rip), %al      # 0x7943e
movb %al, -0x89(%rbp)
leaq -0x89(%rbp), %rsi
movl $0x1, %edx
callq 0x58340
andb $0x1, %al
movb %al, -0x1(%rbp)
movb -0x1(%rbp), %al
andb $0x1, %al
addq $0xa0, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)