国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發(fā)設計 > 正文

live555學習筆記3-消息循環(huán)

2019-11-08 18:28:29
字體:
來源:轉載
供稿:網友

三 消息循環(huán)

看服端的主體:live555MediaServer.cpp中的main()函數(shù),可見其創(chuàng)建一個RTSPServer類實例后,即進入一個函數(shù)env->taskScheduler().doEventLoop()中,看名字很明顯是一個消息循壞,執(zhí)行到里面后不停地轉圈,生名不息,轉圈不止。那么在這個人生的圈圈中如何實現(xiàn)RTSP服務和RTP傳輸呢?別想那么遠了,還是先看這個圈圈中實現(xiàn)了什么功能吧。

[cpp] view plain copyvoid BasicTaskScheduler0::doEventLoop(char* watchVariable) {      // Repeatedly loop, handling readble sockets and timed events:      while (1) {          if (watchVariable != NULL && *watchVariable != 0)              break;          SingleStep();      }  }  BasicTaskScheduler0從TaskScheduler派生,所以還是一個任務調度對象,所以依然說明任務調度對象是整個程序的發(fā)動機。

循環(huán)中每次走一步:SingleStep()。這走一步中都做些什么呢?

總結為以下四步:

1為所有需要操作的socket執(zhí)行select。

2找出第一個應執(zhí)行的socket任務(handler)并執(zhí)行之。

3找到第一個應響應的事件,并執(zhí)行之。

4找到第一個應執(zhí)行的延遲任務并執(zhí)行之。

可見,每一步中只執(zhí)行三個任務隊列中的一項。下面詳細分析函數(shù)SingleStep():

[cpp] view plain copy//循壞中主要執(zhí)行的函數(shù)  void BasicTaskScheduler::SingleStep(unsigned maxDelayTime) {      fd_set readSet = fReadSet; // make a copy for this select() call      fd_set writeSet = fWriteSet; // ditto      fd_set exceptionSet = fExceptionSet; // ditto        //計算select socket們時的超時時間。      DelayInterval const& timeToDelay = fDelayQueue.timeToNextAlarm();      struct timeval tv_timeToDelay;      tv_timeToDelay.tv_sec = timeToDelay.seconds();      tv_timeToDelay.tv_usec = timeToDelay.useconds();      // Very large "tv_sec" values cause select() to fail.      // Don't make it any larger than 1 million seconds (11.5 days)      const long MAX_TV_SEC = MILLION;      if (tv_timeToDelay.tv_sec > MAX_TV_SEC) {          tv_timeToDelay.tv_sec = MAX_TV_SEC;      }      // Also check our "maxDelayTime" parameter (if it's > 0):      if (maxDelayTime > 0              && (tv_timeToDelay.tv_sec > (long) maxDelayTime / MILLION                      || (tv_timeToDelay.tv_sec == (long) maxDelayTime / MILLION                              && tv_timeToDelay.tv_usec                                      > (long) maxDelayTime % MILLION))) {          tv_timeToDelay.tv_sec = maxDelayTime / MILLION;          tv_timeToDelay.tv_usec = maxDelayTime % MILLION;      }        //先執(zhí)行socket的select操作,以確定哪些socket任務(handler)需要執(zhí)行。      int selectResult = select(fMaxNumSockets,              &readSet, &writeSet,&exceptionSet,              &tv_timeToDelay);        if (selectResult < 0) {  //#if defined(__WIN32__) || defined(_WIN32)          int err = WSAGetLastError();          // For some unknown reason, select() in Windoze sometimes fails with WSAEINVAL if          // it was called with no entries set in "readSet".  If this happens, ignore it:          if (err == WSAEINVAL && readSet.fd_count == 0) {              err = EINTR;              // To stop this from happening again, create a dummy socket:              int dummySocketNum = socket(AF_INET, SOCK_DGRAM, 0);              FD_SET((unsigned) dummySocketNum, &fReadSet);          }          if (err != EINTR) {  //#else  //      if (errno != EINTR && errno != EAGAIN) {  //#endif              // Unexpected error - treat this as fatal:  //#if !defined(_WIN32_WCE)  //          perror("BasicTaskScheduler::SingleStep(): select() fails");  //#endif              internalError();          }      }        // Call the handler function for one readable socket:      HandlerIterator iter(*fHandlers);      HandlerDescriptor* handler;      // To ensure forward 
發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 沙坪坝区| 新野县| 东方市| 呼图壁县| 荔波县| 阜城县| 桃源县| 永吉县| 昭通市| 南宫市| 平果县| 呼图壁县| 锦州市| 福清市| 平江县| 安阳县| 张家口市| 汉中市| 阆中市| 南城县| 石景山区| 台东县| 高密市| 泰来县| 凯里市| 永胜县| 临泽县| 台安县| 石狮市| 阜阳市| 阳江市| 兰州市| 嘉义县| 新民市| 密云县| 景洪市| 康保县| 桑植县| 台江县| 定日县| 灌云县|