diff --git a/trunk/src/app/srs_app_srt_server.cpp b/trunk/src/app/srs_app_srt_server.cpp index eaea6b286..bfaef1f8e 100644 --- a/trunk/src/app/srs_app_srt_server.cpp +++ b/trunk/src/app/srs_app_srt_server.cpp @@ -374,15 +374,21 @@ srs_error_t SrsSrtEventLoop::cycle() return srs_error_wrap(err, "srt listener"); } - // Check events fired, return directly. - if ((err = srt_poller_->wait(0)) != srs_success) { - srs_error("srt poll wait failed, err=%s", srs_error_desc(err).c_str()); + // Check and notify fired SRT events by epoll. + // + // Note that the SRT poller use a dedicated and isolated epoll, which is not the same as the one of SRS, in + // short, the wait won't switch to other coroutines when no fd is active, so we must use timeout(0) to make sure + // to return directly, then use srs_usleep to do the coroutine switch. + int n_fds = 0; + if ((err = srt_poller_->wait(0, &n_fds)) != srs_success) { + srs_warn("srt poll wait failed, n_fds=%d, err=%s", n_fds, srs_error_desc(err).c_str()); srs_error_reset(err); } - // Schedule srt event by state-thread. - srs_usleep(1 * SRS_UTIME_MILLISECONDS); + // We use sleep to switch to other coroutines, because the SRT poller is not possible to do this. + srs_usleep((n_fds ? 1 : 10) * SRS_UTIME_MILLISECONDS); } return err; } + diff --git a/trunk/src/protocol/srs_service_st_srt.cpp b/trunk/src/protocol/srs_service_st_srt.cpp index 5809ddecb..d2f580911 100644 --- a/trunk/src/protocol/srs_service_st_srt.cpp +++ b/trunk/src/protocol/srs_service_st_srt.cpp @@ -450,12 +450,14 @@ srs_error_t SrsSrtPoller::del_socket(SrsSrtSocket* srt_skt) return err; } -srs_error_t SrsSrtPoller::wait(int timeout_ms) +srs_error_t SrsSrtPoller::wait(int timeout_ms, int* pn_fds) { srs_error_t err = srs_success; // wait srt event fired, will timeout after `timeout_ms` milliseconds. int ret = srt_epoll_uwait(srt_epoller_fd_, events_.data(), events_.size(), timeout_ms); + *pn_fds = ret; + if (ret < 0) { return srs_error_new(ERROR_SRT_EPOLL, "srt_epoll_uwait, ret=%d, err=%s", ret, srt_getlasterror_str()); } diff --git a/trunk/src/protocol/srs_service_st_srt.hpp b/trunk/src/protocol/srs_service_st_srt.hpp index f2d1f7755..c96d07110 100644 --- a/trunk/src/protocol/srs_service_st_srt.hpp +++ b/trunk/src/protocol/srs_service_st_srt.hpp @@ -77,7 +77,9 @@ public: srs_error_t add_socket(SrsSrtSocket* srt_skt); srs_error_t mod_socket(SrsSrtSocket* srt_skt); srs_error_t del_socket(SrsSrtSocket* srt_skt); - srs_error_t wait(int timeout_ms); + // Wait for the fds in its epoll to be fired in specified timeout_ms, where the pn_fds is the number of active fds. + // Note that for ST, please always use timeout_ms(0) and switch coroutine by yourself. + srs_error_t wait(int timeout_ms, int* pn_fds); private: // Find SrsSrtSocket* context by SRTSOCKET. std::map fd_sockets_;