标签:
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 }
这个函数很长。在文件BasicUsageEnvironment\BasicTaskScheduler.cpp里面,从第66行到第213行,共147行。
标签:
原文地址:http://www.cnblogs.com/liyou-blog/p/4211228.html