Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

how to exit quickly from srt_epoll_wait #2923

Open
kgbook opened this issue Apr 11, 2024 · 1 comment
Open

how to exit quickly from srt_epoll_wait #2923

kgbook opened this issue Apr 11, 2024 · 1 comment
Labels
Type: Question Questions or things that require clarification

Comments

@kgbook
Copy link
Contributor

kgbook commented Apr 11, 2024

Under stable network conditions, I expect srt_epoll_wait to block and wait for data, and then play the data once it's received. However, when there are significant changes in network conditions, such as the RTT changing from 300ms to 10ms, I hope to terminate the current SRT data transmission thread, reconfigure the latency, restart the data transmission, and play the data.

My goal is to exit the srt_epoll_wait blocked state as swiftly as possible to facilitate efficient resource cleanup. I am currently planning to use notifyExitWait to exit the blocked state, eliminating the need for the SRT data receive thread to wait for srt_epoll_wait indefinitely.

I initially sought to implement this via a system socket. Nevertheless, as epoll is Linux-specific and not available on iOS, an error occurs during iOS platform compilation stating that the sys/epoll.h and sys/eventfd.h header files cannot be found. To this end, I am considering implementing this functionality using an SRT user socket.

I would like to inquire:

  1. Is there a difference between SRT's user socket and the system socket?
  2. If I write an integer value 1 to the SRT socket with the intention of receiving data to exit the thread, can this be achieved?

Here is some code:

SrtEpoll::SrtEpoll() : epoll_fd_(-1), event_fd_(-1) {
    int epid = srt_epoll_create();
    if (epid < 0)
    {
        LOGE("srt_epoll_create failed, %s", srt_getlasterror_str());
        return ;
    }
    epoll_fd_ = epid;
    initExitEvent();
}

int SrtEpoll::waitReady() {
    if (epoll_fd_ < 0) {
        LOGE("create epoll first please!");
        return -1;
    }
    memset(readyFds_, -1, sizeof(readyFds_));
    int srtrfdslen = sizeof(readyFds_);
    const int timeout_ms = -1;
    return srt_epoll_wait(epoll_fd_, &readyFds_[0], &srtrfdslen, nullptr, nullptr, timeout_ms, nullptr,
                          nullptr, nullptr, nullptr);
}

void SrtEpoll::notifyExitWait() {
    int exit = 1;
    if (epoll_fd_ < 0 || event_fd_ < 0) {
        LOGW("epoll_fd or event_fd not valid or closed already!");
        return;
    }
    write(event_fd_, &exit, sizeof(exit));
}

void SrtEpoll::initExitEvent() {
    if (epoll_fd_ < 0) {
        LOGE("create epoll first please!");
        return;
    }

    event_fd_ = srt_create_socket(); // sys/eventfd.h will not be found in iOS SDK
    if (event_fd_ < 0) {
        LOGE("create eventfd failed, %s", strerror(errno));
        return;
    }
    int events = SRT_EPOLL_IN;
    if (srt_epoll_update_usock(epoll_fd_, event_fd_, &events) < 0) {
        LOGE("srt_epoll_update_usock failed!");
        return ;
    }
}
@kgbook kgbook added the Type: Question Questions or things that require clarification label Apr 11, 2024
@ethouris
Copy link
Collaborator

Sorry that we have noticed this question so late, but here are some information that might be important here:

  1. When you close the socket that was subscribed in one of the EID (epoll_fd_) and this was the last socket in this EID, the srt_epoll_wait will exit with error - at least the default configured one.
  2. You can subscribe the socket in the EID for IN and ERR events - this way you will get the signal also at the moment when this socket is broken or closed.
  3. SRT Sockets are "userspace sockets", or more precisely, they are called "sockets" because of the logical similarity, but they have completely nothing to do with system sockets. If that was the case, we wouldn't need the dedicated srt_epoll_wait function which can be subscribed simultaneously for system socekts and for SRT ("userspace" - hence the "u" letter in srt_epoll_update_usock) sockets.
  4. You can write bytes to the SRT sockets and this will be received if the socket is connected by the peer to which it is connected, that's all.
  5. You can't change the latency on the fly - you would have to close the socket and reconnect.

There's also another waiting function - srt_epoll_uwait, which differs slightly to *_wait in several details, the most important part is that it can also be subscribed to edge-triggered events, but it can work only with EIDs subscribed exclusively for SRT sockets.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Type: Question Questions or things that require clarification
Projects
None yet
Development

No branches or pull requests

2 participants