// File: /workspace/github_c_makefile_star2_O1/samtools[P]htslib/cram/cram_io.c
// Function: cram_close
int cram_close(cram_fd *fd) {
    spare_bams *bl, *next;
    int i, ret = 0;

    if (!fd)
        return -1;

    if (fd->mode == 'w' && fd->ctr) {
        if(fd->ctr->slice)
            cram_update_curr_slice(fd->ctr, fd->version);

        if (-1 == cram_flush_container_mt(fd, fd->ctr))
            ret = -1;
    }

    if (fd->mode != 'w')
        cram_drain_rqueue(fd);

    if (fd->pool && fd->eof >= 0 && fd->rqueue) {
        hts_tpool_process_flush(fd->rqueue);

        if (0 != cram_flush_result(fd))
            ret = -1;

        if (fd->mode == 'w')
            fd->ctr = NULL; // prevent double freeing

        //fprintf(stderr, "CRAM: destroy queue %p\n", fd->rqueue);

        hts_tpool_process_destroy(fd->rqueue);
    }

    pthread_mutex_destroy(&fd->metrics_lock);
    pthread_mutex_destroy(&fd->ref_lock);
    pthread_mutex_destroy(&fd->range_lock);
    pthread_mutex_destroy(&fd->bam_list_lock);

    if (ret == 0 && fd->mode == 'w') {
        /* Write EOF block */
        if (0 != cram_write_eof_block(fd))
            ret = -1;
    }

    for (bl = fd->bl; bl; bl = next) {
        int max_rec = fd->seqs_per_slice * fd->slices_per_container;

        next = bl->next;
        free_bam_list(bl->bams, max_rec);
        free(bl);
    }

    if (hclose(fd->fp) != 0)
        ret = -1;

    if (fd->file_def)
        cram_free_file_def(fd->file_def);

    if (fd->header)
        sam_hdr_destroy(fd->header);

    free(fd->prefix);

    if (fd->ctr)
        cram_free_container(fd->ctr);

    if (fd->ctr_mt && fd->ctr_mt != fd->ctr)
        cram_free_container(fd->ctr_mt);

    if (fd->refs)
        refs_free(fd->refs);
    if (fd->ref_free)
        free(fd->ref_free);

    for (i = 0; i < DS_END; i++)
        if (fd->m[i])
            free(fd->m[i]);

    if (fd->tags_used) {
        khint_t k;

        for (k = kh_begin(fd->tags_used); k != kh_end(fd->tags_used); k++) {
            if (kh_exist(fd->tags_used, k))
                free(kh_val(fd->tags_used, k));
        }

        kh_destroy(m_metrics, fd->tags_used);
    }

    if (fd->index)
        cram_index_free(fd);

    if (fd->own_pool && fd->pool)
        hts_tpool_destroy(fd->pool);

    if (fd->idxfp)
        if (bgzf_close(fd->idxfp) < 0)
            ret = -1;

    free(fd);

    return ret;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
testq %rdi, %rdi
je 0x55df7
movq %rdi, %rbx
xorl %ebp, %ebp
cmpl $0x77, 0x8(%rdi)
jne 0x55bb5
movq 0x38(%rbx), %rdi
testq %rdi, %rdi
je 0x55bb5
cmpq $0x0, 0x90(%rdi)
je 0x55b9e
movl 0xc(%rbx), %esi
callq 0x49dcb
movq 0x38(%rbx), %rsi
movq %rbx, %rdi
callq 0x53b58
xorl %ebp, %ebp
cmpl $-0x1, %eax
sete %bpl
negl %ebp
cmpl $0x77, 0x8(%rbx)
je 0x55bc3
movq %rbx, %rdi
callq 0x40293
cmpq $0x0, 0x88b8(%rbx)
je 0x55c11
cmpl $0x0, 0x8890(%rbx)
js 0x55c11
movq 0x88c0(%rbx), %rdi
testq %rdi, %rdi
je 0x55c11
callq 0x381ae
movq %rbx, %rdi
callq 0x53ccd
xorl %ecx, %ecx
negl %eax
sbbl %ecx, %ecx
cmpl $0x77, 0x8(%rbx)
jne 0x55c03
movq $0x0, 0x38(%rbx)
orl %ecx, %ebp
movq 0x88c0(%rbx), %rdi
callq 0x37316
leaq 0x88c8(%rbx), %rdi
callq 0x4590
leaq 0x88f0(%rbx), %rdi
callq 0x4590
leaq 0x8918(%rbx), %rdi
callq 0x4590
leaq 0x8948(%rbx), %rdi
callq 0x4590
movl $0xffffffff, %r15d      # imm = 0xFFFFFFFF
testl %ebp, %ebp
jne 0x55c64
xorl %r15d, %r15d
cmpl $0x77, 0x8(%rbx)
jne 0x55c64
movq %rbx, %rdi
callq 0x55a3b
xorl %r15d, %r15d
negl %eax
sbbl %r15d, %r15d
movq 0x8940(%rbx), %r14
testq %r14, %r14
je 0x55c99
movl 0x21c(%rbx), %esi
imull 0x214(%rbx), %esi
movq (%r14), %rdi
movq 0x8(%r14), %r12
callq 0x52e36
movq %r14, %rdi
callq 0x45c0
movq %r12, %r14
testq %r12, %r12
jne 0x55c70
movq (%rbx), %rdi
callq 0xf6d0
xorl %ebp, %ebp
negl %eax
sbbl %ebp, %ebp
movq 0x10(%rbx), %rdi
testq %rdi, %rdi
je 0x55cb5
callq 0x45c0
movq 0x18(%rbx), %rdi
testq %rdi, %rdi
je 0x55cc3
callq 0x22ae6
movq 0x20(%rbx), %rdi
callq 0x45c0
movq 0x38(%rbx), %rdi
testq %rdi, %rdi
je 0x55cda
callq 0x5295e
movq 0x40(%rbx), %rdi
testq %rdi, %rdi
je 0x55cee
cmpq 0x38(%rbx), %rdi
je 0x55cee
callq 0x5295e
movq 0x50(%rbx), %rdi
testq %rdi, %rdi
je 0x55cfc
callq 0x507eb
movq 0x60(%rbx), %rdi
testq %rdi, %rdi
je 0x55d0a
callq 0x45c0
orl %r15d, %ebp
movl $0x12, %r14d
movq (%rbx,%r14,8), %rdi
testq %rdi, %rdi
je 0x55d21
callq 0x45c0
incq %r14
cmpq $0x41, %r14
jne 0x55d13
cmpq $0x0, 0x208(%rbx)
je 0x55da6
movq 0x208(%rbx), %r14
cmpl $0x0, (%r14)
je 0x55d83
xorl %r15d, %r15d
xorl %r12d, %r12d
movq 0x10(%r14), %rax
movl %r12d, %ecx
shrl $0x4, %ecx
movl (%rax,%rcx,4), %eax
movl %r15d, %ecx
andb $0x1e, %cl
shrl %cl, %eax
testb $0x3, %al
jne 0x55d70
movq 0x20(%r14), %rax
movl %r12d, %ecx
movq (%rax,%rcx,8), %rdi
callq 0x45c0
incl %r12d
movq 0x208(%rbx), %r14
addl $0x2, %r15d
cmpl (%r14), %r12d
jne 0x55d47
movq 0x18(%r14), %rdi
callq 0x45c0
movq 0x10(%r14), %rdi
callq 0x45c0
movq 0x20(%r14), %rdi
callq 0x45c0
movq %r14, %rdi
callq 0x45c0
cmpq $0x0, 0x8878(%rbx)
je 0x55db8
movq %rbx, %rdi
callq 0x4c574
cmpl $0x0, 0x88b0(%rbx)
je 0x55dd2
movq 0x88b8(%rbx), %rdi
testq %rdi, %rdi
je 0x55dd2
callq 0x3831c
movq 0x8988(%rbx), %rdi
testq %rdi, %rdi
je 0x55ded
callq 0xd4a4
testl %eax, %eax
movl $0xffffffff, %eax       # imm = 0xFFFFFFFF
cmovsl %eax, %ebp
movq %rbx, %rdi
callq 0x45c0
jmp 0x55dfc
movl $0xffffffff, %ebp       # imm = 0xFFFFFFFF
movl %ebp, %eax
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq