您的位置:首页 > 其它

三、消息循环

2015-01-14 11:48 316 查看
 三  消息循环 

看服端的主体:live555MediaServer.cpp 中的 main()函数,可见其创建一个 RTSPServer

类实例后,即进入一个函数 env->taskScheduler().doEventLoop()中,看名字很明显是一个

消息循坏,执行到里面后不停地转圈,生名不息,转圈不止。那么在这个人生的圈圈中如何

实现 RTSP 服务和 RTP 传输呢?别想那么远了,还是先看这个圈圈中实现了什么功能吧。 

[cpp]   

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. }   

BasicTaskScheduler0 从 TaskScheduler 派生,所以还是一个任务调度对象,所以依然说

明任务调度对象是整个程序的发动机。   

循环中每次走一步:SingleStep()。这走一步中都做些什么呢? 总结为以下四步: 

1为所有需要操作的 socket 执行 select。 

2找出第一个应执行的 socket 任务(handler)并执行之。 

3找到第一个应响应的事件,并执行之。 

4找到第一个应执行的延迟任务并执行之。 

可见,每一步中只执行三个任务队列中的一项。下面详细分析函数 SingleStep(): 

[cpp] view plaincopyprint? 

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.    

7.     //计算 select socket 们时的超时时间。     

8.     DelayInterval const& timeToDelay = fDelayQueue.timeToNextAlarm();   

9.     struct timeval tv_timeToDelay;   

10.     tv_timeToDelay.tv_sec = timeToDelay.seconds();   

11.     tv_timeToDelay.tv_usec = timeToDelay.useconds();   

12.     // Very large "tv_sec" values cause select() to fail.     

13.     // Don't make it any larger than 1 million seconds (11.5 days)     

14.     const long MAX_TV_SEC = MILLION;   

15.     if (tv_timeToDelay.tv_sec > MAX_TV_SEC) {   

16.         tv_timeToDelay.tv_sec = MAX_TV_SEC;   

17.     }   

18.     // Also check our "maxDelayTime" parameter (if it's > 0):     

19.     if (maxDelayTime > 0   

20.             && (tv_timeToDelay.tv_sec > (long) maxDelayTime / MILLION   

21.                     || (tv_timeToDelay.tv_sec == (long) maxDelayTime / MILLION   

22.                             && tv_timeToDelay.tv_usec   

23.                                     > (long) maxDelayTime % MILLION))) {   24.         tv_timeToDelay.tv_sec = maxDelayTime / MILLION;   

25.         tv_timeToDelay.tv_usec = maxDelayTime % MILLION;   

26.     }   

27.    

28.     //先执行 socket 的 select 操作,以确定哪些 socket 任务(handler)需要执行。     

29.     int selectResult = select(fMaxNumSockets,   

30.             &readSet, &writeSet,&exceptionSet,   

31.             &tv_timeToDelay);   

32.    

33.     if (selectResult < 0) {   

34. //#if defined(__WIN32__) || defined(_WIN32)     

35.         int err = WSAGetLastError();   

36.         // For some unknown reason, select() in Windoze sometimes fails with W

SAEINVAL if     

37.         // it was called with no entries set in "readSet".  If this happens, ignore it: 

   

38.         if (err == WSAEINVAL && readSet.fd_count == 0) {   

39.             err = EINTR;   

40.             // To stop this from happening again, create a dummy socket:     

41.             int dummySocketNum = socket(AF_INET, SOCK_DGRAM, 0);   

42.             FD_SET((unsigned) dummySocketNum, &fReadSet);   

43.         }   

44.         if (err != EINTR) {   

45. //#else     

46. //      if (errno != EINTR && errno != EAGAIN) {     

47. //#endif     

48.             // Unexpected error - treat this as fatal:     

49. //#if !defined(_WIN32_WCE)     

50. //          perror("BasicTaskScheduler::SingleStep(): select() fails");     

51. //#endif     

52.             internalError();   

53.         }   

54.     }   

55.    

56.     // Call the handler function for one readable socket:     57.     HandlerIterator iter(*fHandlers);   

58.     HandlerDescriptor* handler;   

59.     // To ensure forward progress through the handlers, begin past the last     

60.     // socket number that we handled:     

61.     if (fLastHandledSocketNum >= 0) {   

62.         //找到上次执行的 socket handler 的下一个     

63.         while ((handler = iter.next()) != NULL) {   

64.             if (handler->socketNum == fLastHandledSocketNum)   

65.                 break;   

66.         }   

67.         if (handler == NULL) {   

68.             fLastHandledSocketNum = -1;   

69.             iter.reset(); // start from the beginning instead     

70.         }   

71.     }   

72.    

73.     //从找到的 handler 开始,找一个可以执行的 handler,不论其状态是可读,可

写,还是出错,执行之。     

74.     while ((handler = iter.next()) != NULL) {   

75.         int sock = handler->socketNum; // alias     

76.         int resultConditionSet = 0;   

77.         if (FD_ISSET(sock, &readSet)   

78.                 && FD_ISSET(sock, &fReadSet)/*sanity check*/)   

79.             resultConditionSet |= SOCKET_READABLE;   

80.         if (FD_ISSET(sock, &writeSet)   

81.                 && FD_ISSET(sock, &fWriteSet)/*sanity check*/)   

82.             resultConditionSet |= SOCKET_WRITABLE;   

83.         if (FD_ISSET(sock, &exceptionSet)   

84.                 && FD_ISSET(sock, &fExceptionSet)/*sanity check*/)   

85.             resultConditionSet |= SOCKET_EXCEPTION;   

86.         if ((resultConditionSet & handler->conditionSet)   

87.                 != 0 && handler->handlerProc != NULL) {   

88.             fLastHandledSocketNum = sock;   

89.             // Note: we set "fLastHandledSocketNum" before calling the handler,     

90.             // in case the handler calls "doEventLoop()" reentrantly.     91.             (*handler->handlerProc)(handler->clientData, resultConditionSet);   

92.             break;   

93.         }   

94.     }   

95.    

96.     //如果寻找完了依然没有执行任何 handle,则从头再找。     

97.     if (handler == NULL && fLastHandledSocketNum >= 0) {   

98.         // We didn't call a handler, but we didn't get to check all of them,     

99.         // so try again from the beginning:     

100.          iter.reset();   

101.          while ((handler = iter.next()) != NULL) {   

102.              int sock = handler-&g
4000
t;socketNum; // alias     

103.              int resultConditionSet = 0;   

104.              if (FD_ISSET(sock, &readSet)&& FD_ISSET(sock, &fReadSet)/*san

ity check*/)   

105.                  resultConditionSet |= SOCKET_READABLE;   

106.              if (FD_ISSET(sock, &writeSet)&& FD_ISSET(sock, &fWriteSet)/*san

ity check*/)   

107.                  resultConditionSet |= SOCKET_WRITABLE;   

108.              if (FD_ISSET(sock, &exceptionSet)   && FD_ISSET(sock, &fExcepti

onSet)/*sanity check*/)   

109.                  resultConditionSet |= SOCKET_EXCEPTION;   

110.              if ((resultConditionSet & handler->conditionSet)   

111.                      != 0 && handler->handlerProc != NULL) {   

112.                  fLastHandledSocketNum = sock;   

113.                  // Note: we set "fLastHandledSocketNum" before calling the handl

er,     

114.                  // in case the handler calls "doEventLoop()" reentrantly.     

115.                  (*handler->handlerProc)(handler->clientData, resultConditionSet); 

116.                  break;   

117.              }   

118.          }   

119.          //依然没有找到可执行的 handler。     

120.          if (handler == NULL)   

121.              fLastHandledSocketNum = -1; //because we didn't call a handler     122.      }   

123.      //响应事件     

124.      // Also handle any newly-triggered event     

125.      // (Note that we do this *after* calling a socket handler,     

126.      // in case the triggered event handler modifies The set of readable socket

s.)     

127.      if (fTriggersAwaitingHandling != 0) {   

128.          if (fTriggersAwaitingHandling == fLastUsedTriggerMask) {   

129.              // Common-case optimization for a single event trigger:     

130.              fTriggersAwaitingHandling = 0;   

131.              if (fTriggeredEventHandlers[fLastUsedTriggerNum] != NULL) {   

132.                  //执行一个事件处理函数     

133.                  (*fTriggeredEventHandlers[fLastUsedTriggerNum])(fTriggeredEv

entClientDatas[fLastUsedTriggerNum]);   

134.              }   

135.          } else {   

136.              // Look for an event trigger that needs handling     

137.              // (making sure that we make forward progress through all possible t

riggers):     

138.              unsigned i = fLastUsedTriggerNum;   

139.              EventTriggerId mask = fLastUsedTriggerMask;   

140.              do {   

141.                  i = (i + 1) % MAX_NUM_EVENT_TRIGGERS;   

142.                  mask >>= 1;   

143.                  if (mask == 0)   

144.                      mask = 0x80000000;   

145.                  if ((fTriggersAwaitingHandling & mask) != 0) {   

146.                      //执行一个事件响应     

147.                      fTriggersAwaitingHandling &= ~mask;   

148.                      if (fTriggeredEventHandlers[i] != NULL) {   

149.                          (*fTriggeredEventHandlers[i])(fTriggeredEventClientDatas[i])

;   

150.                      }   

151.                      fLastUsedTriggerMask = mask;   

152.                      fLastUsedTriggerNum = i;   153.                      break;   

154.                  }   

155.              } while (i != fLastUsedTriggerNum);   

156.          }   

157.      }   

158.      //执行一个最迫切的延迟任务。     

159.      // Also handle any delayed event that may have come due.     

160.      fDelayQueue.handleAlarm();   

161.  }   
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  rtsp 流媒体 live555