码迷,mamicode.com
首页 > 其他好文 > 详细

live555分析

时间:2015-01-08 17:20:38      阅读:459      评论:0      收藏:0      [点我收藏+]

标签:

live555的核心函数是void BasicTaskScheduler::SingleStep(unsigned maxDelayTime):

技术分享
  1 void BasicTaskScheduler::SingleStep(unsigned maxDelayTime) {
  2   fd_set readSet = fReadSet; // make a copy for this select() call
  3   fd_set writeSet = fWriteSet; // ditto
  4   fd_set exceptionSet = fExceptionSet; // ditto
  5 
  6   DelayInterval const& timeToDelay = fDelayQueue.timeToNextAlarm();
  7   struct timeval tv_timeToDelay;
  8   tv_timeToDelay.tv_sec = timeToDelay.seconds();
  9   tv_timeToDelay.tv_usec = timeToDelay.useconds();
 10   // Very large "tv_sec" values cause select() to fail.
 11   // Don‘t make it any larger than 1 million seconds (11.5 days)
 12   const long MAX_TV_SEC = MILLION;
 13   if (tv_timeToDelay.tv_sec > MAX_TV_SEC) {
 14     tv_timeToDelay.tv_sec = MAX_TV_SEC;
 15   }
 16   // Also check our "maxDelayTime" parameter (if it‘s > 0):
 17   if (maxDelayTime > 0 &&
 18       (tv_timeToDelay.tv_sec > (long)maxDelayTime/MILLION ||
 19        (tv_timeToDelay.tv_sec == (long)maxDelayTime/MILLION &&
 20     tv_timeToDelay.tv_usec > (long)maxDelayTime%MILLION))) {
 21     tv_timeToDelay.tv_sec = maxDelayTime/MILLION;
 22     tv_timeToDelay.tv_usec = maxDelayTime%MILLION;
 23   }
 24 
 25   int selectResult = select(fMaxNumSockets, &readSet, &writeSet, &exceptionSet, &tv_timeToDelay);
 26   if (selectResult < 0) {
 27 #if defined(__WIN32__) || defined(_WIN32)
 28     int err = WSAGetLastError();
 29     // For some unknown reason, select() in Windoze sometimes fails with WSAEINVAL if
 30     // it was called with no entries set in "readSet".  If this happens, ignore it:
 31     if (err == WSAEINVAL && readSet.fd_count == 0) {
 32       err = EINTR;
 33       // To stop this from happening again, create a dummy socket:
 34       if (fDummySocketNum >= 0) closeSocket(fDummySocketNum);
 35       fDummySocketNum = socket(AF_INET, SOCK_DGRAM, 0);
 36       FD_SET((unsigned)fDummySocketNum, &fReadSet);
 37     }
 38     if (err != EINTR) {
 39 #else
 40     if (errno != EINTR && errno != EAGAIN) {
 41 #endif
 42     // Unexpected error - treat this as fatal:
 43 #if !defined(_WIN32_WCE)
 44     perror("BasicTaskScheduler::SingleStep(): select() fails");
 45     // Because this failure is often "Bad file descriptor" - which is caused by an invalid socket number (i.e., a socket number
 46     // that had already been closed) being used in "select()" - we print out the sockets that were being used in "select()",
 47     // to assist in debugging:
 48     fprintf(stderr, "socket numbers used in the select() call:");
 49     for (int i = 0; i < 10000; ++i) {
 50       if (FD_ISSET(i, &fReadSet) || FD_ISSET(i, &fWriteSet) || FD_ISSET(i, &fExceptionSet)) {
 51         fprintf(stderr, " %d(", i);
 52         if (FD_ISSET(i, &fReadSet)) fprintf(stderr, "r");
 53         if (FD_ISSET(i, &fWriteSet)) fprintf(stderr, "w");
 54         if (FD_ISSET(i, &fExceptionSet)) fprintf(stderr, "e");
 55         fprintf(stderr, ")");
 56       }
 57     }
 58     fprintf(stderr, "\n");
 59 #endif
 60     internalError();
 61       }
 62   }
 63 
 64   // Call the handler function for one readable socket:
 65   HandlerIterator iter(*fHandlers);
 66   HandlerDescriptor* handler;
 67   // To ensure forward progress through the handlers, begin past the last
 68   // socket number that we handled:
 69   if (fLastHandledSocketNum >= 0) {
 70     while ((handler = iter.next()) != NULL) {
 71       if (handler->socketNum == fLastHandledSocketNum) break;
 72     }
 73     if (handler == NULL) {
 74       fLastHandledSocketNum = -1;
 75       iter.reset(); // start from the beginning instead
 76     }
 77   }
 78   while ((handler = iter.next()) != NULL) {
 79     int sock = handler->socketNum; // alias
 80     int resultConditionSet = 0;
 81     if (FD_ISSET(sock, &readSet) && FD_ISSET(sock, &fReadSet)/*sanity check*/) resultConditionSet |= SOCKET_READABLE;
 82     if (FD_ISSET(sock, &writeSet) && FD_ISSET(sock, &fWriteSet)/*sanity check*/) resultConditionSet |= SOCKET_WRITABLE;
 83     if (FD_ISSET(sock, &exceptionSet) && FD_ISSET(sock, &fExceptionSet)/*sanity check*/) resultConditionSet |= SOCKET_EXCEPTION;
 84     if ((resultConditionSet&handler->conditionSet) != 0 && handler->handlerProc != NULL) {
 85       fLastHandledSocketNum = sock;
 86           // Note: we set "fLastHandledSocketNum" before calling the handler,
 87           // in case the handler calls "doEventLoop()" reentrantly.
 88       (*handler->handlerProc)(handler->clientData, resultConditionSet);
 89       break;
 90     }
 91   }
 92   if (handler == NULL && fLastHandledSocketNum >= 0) {
 93     // We didn‘t call a handler, but we didn‘t get to check all of them,
 94     // so try again from the beginning:
 95     iter.reset();
 96     while ((handler = iter.next()) != NULL) {
 97       int sock = handler->socketNum; // alias
 98       int resultConditionSet = 0;
 99       if (FD_ISSET(sock, &readSet) && FD_ISSET(sock, &fReadSet)/*sanity check*/) resultConditionSet |= SOCKET_READABLE;
100       if (FD_ISSET(sock, &writeSet) && FD_ISSET(sock, &fWriteSet)/*sanity check*/) resultConditionSet |= SOCKET_WRITABLE;
101       if (FD_ISSET(sock, &exceptionSet) && FD_ISSET(sock, &fExceptionSet)/*sanity check*/) resultConditionSet |= SOCKET_EXCEPTION;
102       if ((resultConditionSet&handler->conditionSet) != 0 && handler->handlerProc != NULL) {
103     fLastHandledSocketNum = sock;
104         // Note: we set "fLastHandledSocketNum" before calling the handler,
105             // in case the handler calls "doEventLoop()" reentrantly.
106     (*handler->handlerProc)(handler->clientData, resultConditionSet);
107     break;
108       }
109     }
110     if (handler == NULL) fLastHandledSocketNum = -1;//because we didn‘t call a handler
111   }
112 
113   // Also handle any newly-triggered event (Note that we do this *after* calling a socket handler,
114   // in case the triggered event handler modifies The set of readable sockets.)
115   if (fTriggersAwaitingHandling != 0) {
116     if (fTriggersAwaitingHandling == fLastUsedTriggerMask) {
117       // Common-case optimization for a single event trigger:
118       fTriggersAwaitingHandling = 0;
119       if (fTriggeredEventHandlers[fLastUsedTriggerNum] != NULL) {
120     (*fTriggeredEventHandlers[fLastUsedTriggerNum])(fTriggeredEventClientDatas[fLastUsedTriggerNum]);
121       }
122     } else {
123       // Look for an event trigger that needs handling (making sure that we make forward progress through all possible triggers):
124       unsigned i = fLastUsedTriggerNum;
125       EventTriggerId mask = fLastUsedTriggerMask;
126 
127       do {
128     i = (i+1)%MAX_NUM_EVENT_TRIGGERS;
129     mask >>= 1;
130     if (mask == 0) mask = 0x80000000;
131 
132     if ((fTriggersAwaitingHandling&mask) != 0) {
133       fTriggersAwaitingHandling &=~ mask;
134       if (fTriggeredEventHandlers[i] != NULL) {
135         (*fTriggeredEventHandlers[i])(fTriggeredEventClientDatas[i]);
136       }
137 
138       fLastUsedTriggerMask = mask;
139       fLastUsedTriggerNum = i;
140       break;
141     }
142       } while (i != fLastUsedTriggerNum);
143     }
144   }
145 
146   // Also handle any delayed event that may have come due.
147   fDelayQueue.handleAlarm();
148 }
View Code

这个函数很长。在文件BasicUsageEnvironment\BasicTaskScheduler.cpp里面,从第66行到第213行,共147行。

live555分析

标签:

原文地址:http://www.cnblogs.com/liyou-blog/p/4211228.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!