Chinaunix首页 | 论坛 | 博客
  • 博客访问: 177581
  • 博文数量: 22
  • 博客积分: 1586
  • 博客等级: 上尉
  • 技术积分: 230
  • 用 户 组: 普通用户
  • 注册时间: 2010-01-06 10:32
文章分类

全部博文(22)

文章存档

2015年(2)

2014年(1)

2013年(2)

2012年(5)

2011年(1)

2010年(11)

我的朋友

分类: LINUX

2012-07-19 15:37:54

三 消息循环

看服端的主体:live555MediaServer.cpp中的main()函数,可见其创建一个RTSPServer类实例后,即进入一个函数env->taskScheduler().doEventLoop()中,看名字很明显是一个消息循坏,执行到里面后不停地转圈,生名不息,转圈不止。那么在这个人生的圈圈中如何实现RTSP服务和RTP传输呢?别想那么远了,还是先看这个圈圈中实现了什么功能吧。


 

点击(此处)折叠或打开

  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():


 

点击(此处)折叠或打开

  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)/*sanity check*/)
  74.             resultConditionSet |= SOCKET_READABLE;
  75.         if (FD_ISSET(sock, &writeSet)
  76.                 && FD_ISSET(sock, &fWriteSet)/*sanity check*/)
  77.             resultConditionSet |= SOCKET_WRITABLE;
  78.         if (FD_ISSET(sock, &exceptionSet)
  79.                 && FD_ISSET(sock, &fExceptionSet)/*sanity check*/)
  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)/*sanity check*/)
  99.                 resultConditionSet |= SOCKET_READABLE;
  100.             if (FD_ISSET(sock, &writeSet)&& FD_ISSET(sock, &fWriteSet)/*sanity check*/)
  101.                 resultConditionSet |= SOCKET_WRITABLE;
  102.             if (FD_ISSET(sock, &exceptionSet)    && FD_ISSET(sock, &fExceptionSet)/*sanity check*/)
  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. }


 

阅读(5094) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~