首页 > 代码库 > live555分析

live555分析

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 handler111   }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分析