// File: /workspace/github_cpp_makefile_star2_O2/hzeller[P]FlaschenTaschen-PixelPusher-bridge/ft-server.cc
// Function: udp_server_run_blocking(CompositeFlaschenTaschen*, ft::Mutex*)
void udp_server_run_blocking(CompositeFlaschenTaschen *display,
                             ft::Mutex *mutex) {
    static const int kBufferSize = 65535;  // maximum UDP has to offer.
    char *packet_buffer = new char[kBufferSize];
    bzero(packet_buffer, kBufferSize);

    struct sigaction sa = {{0}};  // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53119
    sa.sa_handler = InterruptHandler;
    sigaction(SIGTERM, &sa, NULL);
    sigaction(SIGINT, &sa, NULL);

    for (;;) {
        // TODO: also store src-address in case we want to do rate-limiting
        // per source-address.
        ssize_t received_bytes = recvfrom(server_socket,
                                          packet_buffer, kBufferSize,
                                          0, NULL, 0);
        if (interrupt_received)
            break;

        if (received_bytes < 0 && errno == EINTR) // Other signals. Don't care.
            continue;

        if (received_bytes < 0) {
            perror("Trouble receiving.");
            break;
        }

        ImageMetaInfo img_info = {0};
        img_info.width = display->width();  // defaults.
        img_info.height = display->height();

        const char *pixel_pos = ReadImageData(packet_buffer, received_bytes,
                                              &img_info);
        mutex->Lock();
        display->SetLayer(img_info.layer);
        for (int y = 0; y < img_info.height; ++y) {
            for (int x = 0; x < img_info.width; ++x) {
                Color c;
                c.r = *pixel_pos++;
                c.g = *pixel_pos++;
                c.b = *pixel_pos++;
                display->SetPixel(x + img_info.offset_x,
                                  y + img_info.offset_y,
                                  c);
            }
        }
        display->Send();
        display->SetLayer(0);  // Back to sane default.
        mutex->Unlock();
    }
    delete [] packet_buffer;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
subq $0xc8, %rsp
movq %rsi, 0x28(%rsp)
movq %rdi, %r15
movl $0xffff, %edi           # imm = 0xFFFF
callq 0x2040
movq %rax, %rbx
movl $0xffff, %edx           # imm = 0xFFFF
movq %rax, %rdi
xorl %esi, %esi
callq 0x2100
leaq 0x38(%rsp), %r12
movl $0x90, %edx
movq %r12, %rdi
xorl %esi, %esi
callq 0x2100
leaq 0x155(%rip), %rax       # 0x2b5a
movq %rax, -0x8(%r12)
pushq $0xf
popq %rdi
leaq 0x30(%rsp), %r12
movq %r12, %rsi
xorl %edx, %edx
callq 0x2220
pushq $0x2
popq %rdi
movq %r12, %rsi
xorl %edx, %edx
callq 0x2220
leaq 0xd(%rsp), %r13
movl 0x5804(%rip), %edi      # 0x8238
movl $0xffff, %edx           # imm = 0xFFFF
movq %rbx, %rsi
xorl %ecx, %ecx
xorl %r8d, %r8d
xorl %r9d, %r9d
callq 0x2170
cmpb $0x0, 0x57f1(%rip)      # 0x8241
jne 0x2b40
movq %rax, %rbp
testq %rax, %rax
js 0x2b26
xorps %xmm0, %xmm0
movaps %xmm0, 0x10(%rsp)
andq $0x0, 0x20(%rsp)
movq (%r15), %rax
movq %r15, %rdi
callq *0x10(%rax)
movl %eax, 0x10(%rsp)
movq (%r15), %rax
movq %r15, %rdi
callq *0x18(%rax)
movl %eax, 0x14(%rsp)
movq %rbx, %rdi
movq %rbp, %rsi
leaq 0x10(%rsp), %rdx
callq 0x3568
movq %rax, %rbp
movq 0x28(%rsp), %rdi
callq 0x22a0
movl 0x24(%rsp), %esi
movq %r15, %rdi
callq 0x2ee6
xorl %r12d, %r12d
cmpl 0x14(%rsp), %r12d
jge 0x2b04
xorl %r14d, %r14d
cmpl 0x10(%rsp), %r14d
jge 0x2aff
movb (%rbp), %al
movb %al, 0xd(%rsp)
movb 0x1(%rbp), %al
movb %al, 0xe(%rsp)
movb 0x2(%rbp), %al
addq $0x3, %rbp
movb %al, 0xf(%rsp)
movl 0x1c(%rsp), %esi
addl %r14d, %esi
movl 0x20(%rsp), %edx
addl %r12d, %edx
movq (%r15), %rax
movq %r15, %rdi
movq %r13, %rcx
callq *0x20(%rax)
incl %r14d
jmp 0x2ac0
incl %r12d
jmp 0x2ab6
movq (%r15), %rax
movq %r15, %rdi
callq *0x28(%rax)
movq %r15, %rdi
xorl %esi, %esi
callq 0x2ee6
movq 0x28(%rsp), %rdi
callq 0x2160
jmp 0x2a2e
callq 0x2050
cmpl $0x4, (%rax)
je 0x2a2e
leaq 0x2744(%rip), %rdi      # 0x527f
callq 0x21a0
movq %rbx, %rdi
callq 0x2240
addq $0xc8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq