| 975 | } |
| 976 | |
| 977 | static int udp_read(URLContext *h, uint8_t *buf, int size) |
| 978 | { |
| 979 | UDPContext *s = h->priv_data; |
| 980 | int ret; |
| 981 | #if HAVE_PTHREAD_CANCEL |
| 982 | int avail, nonblock = h->flags & AVIO_FLAG_NONBLOCK; |
| 983 | |
| 984 | if (s->rx_fifo) { |
| 985 | pthread_mutex_lock(&s->mutex); |
| 986 | do { |
| 987 | avail = av_fifo_can_read(s->rx_fifo); |
| 988 | if (avail) { // >=size) { |
| 989 | UDPQueuedPacketHeader header; |
| 990 | |
| 991 | av_fifo_read(s->rx_fifo, &header, sizeof(header)); |
| 992 | |
| 993 | s->last_recv_addr = header.addr; |
| 994 | s->last_recv_addr_len = header.addr_len; |
| 995 | |
| 996 | avail = header.pkt_size; |
| 997 | if(avail > size){ |
| 998 | av_log(h, AV_LOG_WARNING, "Part of datagram lost due to insufficient buffer size\n"); |
| 999 | avail = size; |
| 1000 | } |
| 1001 | |
| 1002 | av_fifo_read(s->rx_fifo, buf, avail); |
| 1003 | av_fifo_drain2(s->rx_fifo, header.pkt_size - avail); |
| 1004 | pthread_mutex_unlock(&s->mutex); |
| 1005 | return avail; |
| 1006 | } else if(s->circular_buffer_error){ |
| 1007 | int err = s->circular_buffer_error; |
| 1008 | pthread_mutex_unlock(&s->mutex); |
| 1009 | return err; |
| 1010 | } else if(nonblock) { |
| 1011 | pthread_mutex_unlock(&s->mutex); |
| 1012 | return AVERROR(EAGAIN); |
| 1013 | } else { |
| 1014 | /* FIXME: using the monotonic clock would be better, |
| 1015 | but it does not exist on all supported platforms. */ |
| 1016 | int64_t t = av_gettime() + 100000; |
| 1017 | struct timespec tv = { .tv_sec = t / 1000000, |
| 1018 | .tv_nsec = (t % 1000000) * 1000 }; |
| 1019 | int err = pthread_cond_timedwait(&s->cond, &s->mutex, &tv); |
| 1020 | if (err) { |
| 1021 | pthread_mutex_unlock(&s->mutex); |
| 1022 | return AVERROR(err == ETIMEDOUT ? EAGAIN : err); |
| 1023 | } |
| 1024 | nonblock = 1; |
| 1025 | } |
| 1026 | } while(1); |
| 1027 | } |
| 1028 | #endif |
| 1029 | |
| 1030 | if (!(h->flags & AVIO_FLAG_NONBLOCK)) { |
| 1031 | ret = ff_network_wait_fd(s->udp_fd, 0); |
| 1032 | if (ret < 0) |
| 1033 | return ret; |
| 1034 | } |
nothing calls this directly
no test coverage detected