首页 > 代码库 > 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 }
这个函数很长。在文件BasicUsageEnvironment\BasicTaskScheduler.cpp里面,从第66行到第213行,共147行。
live555分析
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。