| 527 | |
| 528 | #if HAVE_PTHREAD_CANCEL |
| 529 | static void *circular_buffer_task_rx( void *_URLContext) |
| 530 | { |
| 531 | URLContext *h = _URLContext; |
| 532 | UDPContext *s = h->priv_data; |
| 533 | int old_cancelstate; |
| 534 | |
| 535 | ff_thread_setname("udp-rx"); |
| 536 | |
| 537 | pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_cancelstate); |
| 538 | pthread_mutex_lock(&s->mutex); |
| 539 | if (ff_socket_nonblock(s->udp_fd, 0) < 0) { |
| 540 | av_log(h, AV_LOG_ERROR, "Failed to set blocking mode"); |
| 541 | s->circular_buffer_error = AVERROR(EIO); |
| 542 | goto end; |
| 543 | } |
| 544 | while(1) { |
| 545 | UDPQueuedPacketHeader pkt_header; |
| 546 | pkt_header.addr_len = sizeof(pkt_header.addr); |
| 547 | |
| 548 | pthread_mutex_unlock(&s->mutex); |
| 549 | /* Blocking operations are always cancellation points; |
| 550 | see "General Information" / "Thread Cancellation Overview" |
| 551 | in Single Unix. */ |
| 552 | pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &old_cancelstate); |
| 553 | pkt_header.pkt_size = recvfrom(s->udp_fd, s->tmp + sizeof(pkt_header), sizeof(s->tmp) - sizeof(pkt_header), 0, (struct sockaddr *)&pkt_header.addr, &pkt_header.addr_len); |
| 554 | pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_cancelstate); |
| 555 | pthread_mutex_lock(&s->mutex); |
| 556 | if (pkt_header.pkt_size < 0) { |
| 557 | if (ff_neterrno() != AVERROR(EAGAIN) && ff_neterrno() != AVERROR(EINTR)) { |
| 558 | s->circular_buffer_error = ff_neterrno(); |
| 559 | goto end; |
| 560 | } |
| 561 | continue; |
| 562 | } |
| 563 | if (ff_ip_check_source_lists(&pkt_header.addr, &s->filters)) |
| 564 | continue; |
| 565 | memcpy(s->tmp, &pkt_header, sizeof(pkt_header)); |
| 566 | |
| 567 | if (av_fifo_can_write(s->rx_fifo) < pkt_header.pkt_size + sizeof(pkt_header)) { |
| 568 | /* No Space left */ |
| 569 | if (s->overrun_nonfatal) { |
| 570 | av_log(h, AV_LOG_WARNING, "Circular buffer overrun. " |
| 571 | "Surviving due to overrun_nonfatal option\n"); |
| 572 | continue; |
| 573 | } else { |
| 574 | av_log(h, AV_LOG_ERROR, "Circular buffer overrun. " |
| 575 | "To avoid, increase fifo_size URL option. " |
| 576 | "To survive in such case, use overrun_nonfatal option\n"); |
| 577 | s->circular_buffer_error = AVERROR(EIO); |
| 578 | goto end; |
| 579 | } |
| 580 | } |
| 581 | av_fifo_write(s->rx_fifo, s->tmp, pkt_header.pkt_size + sizeof(pkt_header)); |
| 582 | pthread_cond_signal(&s->cond); |
| 583 | } |
| 584 | |
| 585 | end: |
| 586 | pthread_cond_signal(&s->cond); |
nothing calls this directly
no test coverage detected