天天看點

live555學習筆記3-消息循環

三 消息循環

看服端的主體:live555MediaServer.cpp中的main()函數,可見其建立一個RTSPServer類執行個體後,即進入一個函數env->taskScheduler().doEventLoop()中,看名字很明顯是一個消息循壞,執行到裡面後不停地轉圈,生名不息,轉圈不止。那麼在這個人生的圈圈中如何實作RTSP服務和RTP傳輸呢?别想那麼遠了,還是先看這個圈圈中實作了什麼功能吧。

[cpp] view plain copy print ?

  1. void BasicTaskScheduler0::doEventLoop(char* watchVariable) {  
  2.     // Repeatedly loop, handling readble sockets and timed events:   
  3.     while (1) {  
  4.         if (watchVariable != NULL && *watchVariable != 0)  
  5.             break;  
  6.         SingleStep();  
  7.     }  
  8. }  

void BasicTaskScheduler0::doEventLoop(char* watchVariable) {

// Repeatedly loop, handling readble sockets and timed events:

while (1) {

if (watchVariable != NULL && *watchVariable != 0)

break;

SingleStep();

}

}BasicTaskScheduler0從TaskScheduler派生,是以還是一個任務排程對象,是以依然說明任務排程對象是整個程式的發動機。

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

總結為以下四步:

1為所有需要操作的socket執行select。

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

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

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

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

[cpp] view plain copy print ?

  1. //循壞中主要執行的函數   
  2. void BasicTaskScheduler::SingleStep(unsigned maxDelayTime) {  
  3.     fd_set readSet = fReadSet; // make a copy for this select() call   
  4.     fd_set writeSet = fWriteSet; // ditto   
  5.     fd_set exceptionSet = fExceptionSet; // ditto   
  6.     //計算select socket們時的逾時時間。   
  7.     DelayInterval const& timeToDelay = fDelayQueue.timeToNextAlarm();  
  8.     struct timeval tv_timeToDelay;  
  9.     tv_timeToDelay.tv_sec = timeToDelay.seconds();  
  10.     tv_timeToDelay.tv_usec = timeToDelay.useconds();  
  11.     // Very large "tv_sec" values cause select() to fail.   
  12.     // Don't make it any larger than 1 million seconds (11.5 days)   
  13.     const long MAX_TV_SEC = MILLION;  
  14.     if (tv_timeToDelay.tv_sec > MAX_TV_SEC) {  
  15.         tv_timeToDelay.tv_sec = MAX_TV_SEC;  
  16.     }  
  17.     // Also check our "maxDelayTime" parameter (if it's > 0):   
  18.     if (maxDelayTime > 0  
  19.             && (tv_timeToDelay.tv_sec > (long) maxDelayTime / MILLION  
  20.                     || (tv_timeToDelay.tv_sec == (long) maxDelayTime / MILLION  
  21.                             && tv_timeToDelay.tv_usec  
  22.                                     > (long) maxDelayTime % MILLION))) {  
  23.         tv_timeToDelay.tv_sec = maxDelayTime / MILLION;  
  24.         tv_timeToDelay.tv_usec = maxDelayTime % MILLION;  
  25.     }  
  26.     //先執行socket的select操作,以确定哪些socket任務(handler)需要執行。   
  27.     int selectResult = select(fMaxNumSockets,  
  28.             &readSet, &writeSet,&exceptionSet,  
  29.             &tv_timeToDelay);  
  30.     if (selectResult < 0) {  
  31. //#if defined(__WIN32__) || defined(_WIN32)   
  32.         int err = WSAGetLastError();  
  33.         // For some unknown reason, select() in Windoze sometimes fails with WSAEINVAL if   
  34.         // it was called with no entries set in "readSet".  If this happens, ignore it:   
  35.         if (err == WSAEINVAL && readSet.fd_count == 0) {  
  36.             err = EINTR;  
  37.             // To stop this from happening again, create a dummy socket:   
  38.             int dummySocketNum = socket(AF_INET, SOCK_DGRAM, 0);  
  39.             FD_SET((unsigned) dummySocketNum, &fReadSet);  
  40.         }  
  41.         if (err != EINTR) {  
  42. //#else   
  43. //      if (errno != EINTR && errno != EAGAIN) {   
  44. //#endif   
  45.             // Unexpected error - treat this as fatal:   
  46. //#if !defined(_WIN32_WCE)   
  47. //          perror("BasicTaskScheduler::SingleStep(): select() fails");   
  48. //#endif   
  49.             internalError();  
  50.         }  
  51.     }  
  52.     // Call the handler function for one readable socket:   
  53.     HandlerIterator iter(*fHandlers);  
  54.     HandlerDescriptor* handler;  
  55.     // To ensure forward progress through the handlers, begin past the last   
  56.     // socket number that we handled:   
  57.     if (fLastHandledSocketNum >= 0) {  
  58.         //找到上次執行的socket handler的下一個   
  59.         while ((handler = iter.next()) != NULL) {  
  60.             if (handler->socketNum == fLastHandledSocketNum)  
  61.                 break;  
  62.         }  
  63.         if (handler == NULL) {  
  64.             fLastHandledSocketNum = -1;  
  65.             iter.reset(); // start from the beginning instead   
  66.         }  
  67.     }  
  68.     //從找到的handler開始,找一個可以執行的handler,不論其狀态是可讀,可寫,還是出錯,執行之。   
  69.     while ((handler = iter.next()) != NULL) {  
  70.         int sock = handler->socketNum; // alias   
  71.         int resultConditionSet = 0;  
  72.         if (FD_ISSET(sock, &readSet)  
  73.                 && FD_ISSET(sock, &fReadSet))  
  74.             resultConditionSet |= SOCKET_READABLE;  
  75.         if (FD_ISSET(sock, &writeSet)  
  76.                 && FD_ISSET(sock, &fWriteSet))  
  77.             resultConditionSet |= SOCKET_WRITABLE;  
  78.         if (FD_ISSET(sock, &exceptionSet)  
  79.                 && FD_ISSET(sock, &fExceptionSet))  
  80.             resultConditionSet |= SOCKET_EXCEPTION;  
  81.         if ((resultConditionSet & handler->conditionSet)  
  82.                 != 0 && handler->handlerProc != NULL) {  
  83.             fLastHandledSocketNum = sock;  
  84.             // Note: we set "fLastHandledSocketNum" before calling the handler,   
  85.             // in case the handler calls "doEventLoop()" reentrantly.   
  86.             (*handler->handlerProc)(handler->clientData, resultConditionSet);  
  87.             break;  
  88.         }  
  89.     }  
  90.     //如果尋找完了依然沒有執行任何handle,則從頭再找。   
  91.     if (handler == NULL && fLastHandledSocketNum >= 0) {  
  92.         // We didn't call a handler, but we didn't get to check all of them,   
  93.         // so try again from the beginning:   
  94.         iter.reset();  
  95.         while ((handler = iter.next()) != NULL) {  
  96.             int sock = handler->socketNum; // alias   
  97.             int resultConditionSet = 0;  
  98.             if (FD_ISSET(sock, &readSet)&& FD_ISSET(sock, &fReadSet))  
  99.                 resultConditionSet |= SOCKET_READABLE;  
  100.             if (FD_ISSET(sock, &writeSet)&& FD_ISSET(sock, &fWriteSet))  
  101.                 resultConditionSet |= SOCKET_WRITABLE;  
  102.             if (FD_ISSET(sock, &exceptionSet)   && FD_ISSET(sock, &fExceptionSet))  
  103.                 resultConditionSet |= SOCKET_EXCEPTION;  
  104.             if ((resultConditionSet & handler->conditionSet)  
  105.                     != 0 && handler->handlerProc != NULL) {  
  106.                 fLastHandledSocketNum = sock;  
  107.                 // Note: we set "fLastHandledSocketNum" before calling the handler,   
  108.                 // in case the handler calls "doEventLoop()" reentrantly.   
  109.                 (*handler->handlerProc)(handler->clientData, resultConditionSet);  
  110.                 break;  
  111.             }  
  112.         }  
  113.         //依然沒有找到可執行的handler。   
  114.         if (handler == NULL)  
  115.             fLastHandledSocketNum = -1; //because we didn't call a handler   
  116.     }  
  117.     //響應事件   
  118.     // Also handle any newly-triggered event   
  119.     // (Note that we do this *after* calling a socket handler,   
  120.     // in case the triggered event handler modifies The set of readable sockets.)   
  121.     if (fTriggersAwaitingHandling != 0) {  
  122.         if (fTriggersAwaitingHandling == fLastUsedTriggerMask) {  
  123.             // Common-case optimization for a single event trigger:   
  124.             fTriggersAwaitingHandling = 0;  
  125.             if (fTriggeredEventHandlers[fLastUsedTriggerNum] != NULL) {  
  126.                 //執行一個事件處理函數   
  127.                 (*fTriggeredEventHandlers[fLastUsedTriggerNum])(fTriggeredEventClientDatas[fLastUsedTriggerNum]);  
  128.             }  
  129.         } else {  
  130.             // Look for an event trigger that needs handling   
  131.             // (making sure that we make forward progress through all possible triggers):   
  132.             unsigned i = fLastUsedTriggerNum;  
  133.             EventTriggerId mask = fLastUsedTriggerMask;  
  134.             do {  
  135.                 i = (i + 1) % MAX_NUM_EVENT_TRIGGERS;  
  136.                 mask >>= 1;  
  137.                 if (mask == 0)  
  138.                     mask = 0x80000000;  
  139.                 if ((fTriggersAwaitingHandling & mask) != 0) {  
  140.                     //執行一個事件響應   
  141.                     fTriggersAwaitingHandling &= ~mask;  
  142.                     if (fTriggeredEventHandlers[i] != NULL) {  
  143.                         (*fTriggeredEventHandlers[i])(fTriggeredEventClientDatas[i]);  
  144.                     }  
  145.                     fLastUsedTriggerMask = mask;  
  146.                     fLastUsedTriggerNum = i;  
  147.                     break;  
  148.                 }  
  149.             } while (i != fLastUsedTriggerNum);  
  150.         }  
  151.     }  
  152.     //執行一個最迫切的延遲任務。   
  153.     // Also handle any delayed event that may have come due.   
  154.     fDelayQueue.handleAlarm();  
  155. }