MCPcopy Create free account
hub / github.com/FFmpeg/FFmpeg / ff_connect_parallel

Function ff_connect_parallel

libavformat/network.c:404–523  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

402#define NEXT_ATTEMPT_DELAY_MS 200
403
404int ff_connect_parallel(struct addrinfo *addrs, int timeout_ms_per_address,
405 int parallel, URLContext *h, int *fd,
406 int (*customize_fd)(void *, int, int), void *customize_ctx)
407{
408 struct ConnectionAttempt attempts[3];
409 struct pollfd pfd[3];
410 int nb_attempts = 0, i, j;
411 int64_t next_attempt_us = av_gettime_relative(), next_deadline_us;
412 int last_err = AVERROR(EIO);
413 socklen_t optlen;
414 char hostbuf[100], portbuf[20];
415
416 if (parallel > FF_ARRAY_ELEMS(attempts))
417 parallel = FF_ARRAY_ELEMS(attempts);
418
419 print_address_list(h, addrs, "Original list of addresses");
420 // This mutates the list, but the head of the list is still the same
421 // element, so the caller, who owns the list, doesn't need to get
422 // an updated pointer.
423 interleave_addrinfo(addrs);
424 print_address_list(h, addrs, "Interleaved list of addresses");
425
426 while (nb_attempts > 0 || addrs) {
427 // Start a new connection attempt, if possible.
428 if (nb_attempts < parallel && addrs) {
429 getnameinfo(addrs->ai_addr, addrs->ai_addrlen,
430 hostbuf, sizeof(hostbuf), portbuf, sizeof(portbuf),
431 NI_NUMERICHOST | NI_NUMERICSERV);
432 av_log(h, AV_LOG_VERBOSE, "Starting connection attempt to %s port %s\n",
433 hostbuf, portbuf);
434 last_err = start_connect_attempt(&attempts[nb_attempts], &addrs,
435 timeout_ms_per_address, h,
436 customize_fd, customize_ctx);
437 if (last_err < 0) {
438 av_log(h, AV_LOG_VERBOSE, "Connected attempt failed: %s\n",
439 av_err2str(last_err));
440 continue;
441 }
442 if (last_err > 0) {
443 for (i = 0; i < nb_attempts; i++)
444 closesocket(attempts[i].fd);
445 *fd = attempts[nb_attempts].fd;
446 return 0;
447 }
448 pfd[nb_attempts].fd = attempts[nb_attempts].fd;
449 pfd[nb_attempts].events = POLLOUT;
450 next_attempt_us = av_gettime_relative() + NEXT_ATTEMPT_DELAY_MS * 1000;
451 nb_attempts++;
452 }
453
454 av_assert0(nb_attempts > 0);
455 // The connection attempts are sorted from oldest to newest, so the
456 // first one will have the earliest deadline.
457 next_deadline_us = attempts[0].deadline_us;
458 // If we can start another attempt in parallel, wait until that time.
459 if (nb_attempts < parallel && addrs)
460 next_deadline_us = FFMIN(next_deadline_us, next_attempt_us);
461 last_err = ff_poll_interrupt(pfd, nb_attempts,

Callers 1

tcp_openFunction · 0.85

Calls 7

av_gettime_relativeFunction · 0.85
print_address_listFunction · 0.85
interleave_addrinfoFunction · 0.85
av_logFunction · 0.85
start_connect_attemptFunction · 0.85
ff_poll_interruptFunction · 0.85
ff_neterrnoFunction · 0.85

Tested by

no test coverage detected