]> git.sesse.net Git - nageru/commitdiff
Use nonblocking srt_connect(), to allow faster abort on quit.
authorSteinar H. Gunderson <sgunderson@bigfoot.com>
Sun, 17 Sep 2023 15:57:02 +0000 (17:57 +0200)
committerSteinar H. Gunderson <sgunderson@bigfoot.com>
Sun, 17 Sep 2023 15:57:02 +0000 (17:57 +0200)
nageru/video_encoder.cpp

index c1938d505d5e666662e027cd62608b1bc628f376..338428ba16e703235002b00ad28d49dfc3a61dcf 100644 (file)
@@ -388,13 +388,70 @@ int VideoEncoder::connect_to_srt()
                        return sock;
                }
                ++metric_srt_num_connection_attempts;
+
+               // We do a non-blocking connect, so that we can check should_quit
+               // every now and then.
+               int blocking = 0;
+               if (srt_setsockopt(sock, 0, SRTO_RCVSYN, &blocking, sizeof(blocking)) < 0) {
+                       fprintf(stderr, "srt_setsockopt(SRTO_SNDSYN=0): %s\n", srt_getlasterror_str());
+                       srt_close(sock);
+                       continue;
+               }
                if (srt_connect(sock, cur->ai_addr, cur->ai_addrlen) < 0) {
                        fprintf(stderr, "srt_connect(%s): %s\n", print_addrinfo(cur).c_str(), srt_getlasterror_str());
                        srt_close(sock);
                        continue;
                }
-               fprintf(stderr, "Connected to destination SRT endpoint at %s.\n", print_addrinfo(cur).c_str());
-               return sock;
+               int eid = srt_epoll_create();
+               if (eid < 0) {
+                       fprintf(stderr, "srt_epoll_create(): %s\n", srt_getlasterror_str());
+                       srt_close(sock);
+                       continue;
+               }
+               int modes = SRT_EPOLL_ERR | SRT_EPOLL_OUT;
+               if (srt_epoll_add_usock(eid, sock, &modes) < 0) {
+                       fprintf(stderr, "srt_epoll_usock(): %s\n", srt_getlasterror_str());
+                       srt_close(sock);
+                       srt_epoll_release(eid);
+                       continue;
+               }
+               bool ok;
+               while (!should_quit.load()) {
+                       SRTSOCKET errfds[1], writefds[1];
+                       int num_errfds = 1, num_writefds = 1;
+                       int poll_time_ms = 100;
+                       int ret = srt_epoll_wait(eid, errfds, &num_errfds, writefds, &num_writefds, poll_time_ms, 0, 0, 0, 0);
+                       if (ret < 0) {
+                               if (srt_getlasterror(nullptr) == SRT_ETIMEOUT) {
+                                       continue;
+                               } else {
+                                       fprintf(stderr, "srt_epoll_wait(): %s\n", srt_getlasterror_str());
+                                       srt_close(sock);
+                                       srt_epoll_release(eid);
+                                       return -1;
+                               }
+                       } else if (ret > 0) {
+                               // The SRT epoll framework is pretty odd, but seemingly,
+                               // this is the way. Getting the same error code as srt_connect()
+                               // would normally return seems to be impossible, though.
+                               ok = (num_errfds == 0);
+                               break;
+                               fprintf(stderr, "num_errfds=%d num_writefds=%d last_err=%s\n", num_errfds, num_writefds, srt_getlasterror_str());
+                               break;
+                       }
+               }
+               srt_epoll_release(eid);
+               if (should_quit.load()) {
+                       srt_close(sock);
+                       return -1;
+               }
+               if (ok) {
+                       fprintf(stderr, "Connected to destination SRT endpoint at %s.\n", print_addrinfo(cur).c_str());
+                       return sock;
+               } else {
+                       fprintf(stderr, "srt_connect(%s): %s\n", print_addrinfo(cur).c_str(), srt_getlasterror_str());
+                       srt_close(sock);
+               }
        }
 
        // Out of candidates, so give up.