国产探花免费观看_亚洲丰满少妇自慰呻吟_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ā)表
主站蜘蛛池模板: 遂昌县| 佛冈县| 西吉县| 青川县| 汝城县| 织金县| 宝兴县| 保定市| 麟游县| 大同县| 平和县| 东明县| 泸州市| 镇康县| 盈江县| 永善县| 西畴县| 乌拉特中旗| 宁德市| 海门市| 八宿县| 泾阳县| 中超| 繁昌县| 凯里市| 文水县| 卢氏县| 通渭县| 屏边| 呼伦贝尔市| 华坪县| 新泰市| 永福县| 淮阳县| 都安| 木里| 齐齐哈尔市| 襄城县| 大方县| 遂昌县| 大石桥市|