#include <BasicUsageEnvironment.hh>
Inheritance diagram for BasicTaskScheduler:


Public Types | |
| typedef void | BackgroundHandlerProc (void *clientData, int mask) |
Public Member Functions | |
| virtual | ~BasicTaskScheduler () |
| virtual TaskToken | scheduleDelayedTask (int64_t microseconds, TaskFunc *proc, void *clientData) |
| virtual void | unscheduleDelayedTask (TaskToken &prevTask) |
| virtual void | doEventLoop (char *watchVariable) |
| virtual void | rescheduleDelayedTask (TaskToken &task, int64_t microseconds, TaskFunc *proc, void *clientData) |
| virtual void | setBackgroundHandling (int socketNum, int conditionSet, BackgroundHandlerProc *handlerProc, void *clientData)=0 |
| void | disableBackgroundHandling (int socketNum) |
| void | turnOnBackgroundReadHandling (int socketNum, BackgroundHandlerProc *handlerProc, void *clientData) |
| void | turnOffBackgroundReadHandling (int socketNum) |
Static Public Member Functions | |
| static BasicTaskScheduler * | createNew () |
Protected Member Functions | |
| BasicTaskScheduler () | |
| virtual void | SingleStep (unsigned maxDelayTime) |
| virtual void | setBackgroundHandling (int socketNum, int conditionSet, BackgroundHandlerProc *handlerProc, void *clientData) |
| virtual void | moveSocketHandling (int oldSocketNum, int newSocketNum) |
Protected Attributes | |
| int | fMaxNumSockets |
| fd_set | fReadSet |
| fd_set | fWriteSet |
| fd_set | fExceptionSet |
| DelayQueue | fDelayQueue |
| HandlerSet * | fHandlers |
| int | fLastHandledSocketNum |
Definition at line 47 of file BasicUsageEnvironment.hh.
typedef void TaskScheduler::BackgroundHandlerProc(void *clientData, int mask) [inherited] |
Definition at line 121 of file UsageEnvironment.hh.
| BasicTaskScheduler::~BasicTaskScheduler | ( | ) | [virtual] |
| BasicTaskScheduler::BasicTaskScheduler | ( | ) | [protected] |
Definition at line 35 of file BasicTaskScheduler.cpp.
References fExceptionSet, fReadSet, and fWriteSet.
Referenced by createNew().
00036 : fMaxNumSockets(0) { 00037 FD_ZERO(&fReadSet); 00038 FD_ZERO(&fWriteSet); 00039 FD_ZERO(&fExceptionSet); 00040 }
| BasicTaskScheduler * BasicTaskScheduler::createNew | ( | ) | [static] |
Definition at line 31 of file BasicTaskScheduler.cpp.
References BasicTaskScheduler().
Referenced by main().
00031 { 00032 return new BasicTaskScheduler(); 00033 }
| void BasicTaskScheduler::SingleStep | ( | unsigned | maxDelayTime | ) | [protected, virtual] |
Implements BasicTaskScheduler0.
Definition at line 49 of file BasicTaskScheduler.cpp.
References HandlerDescriptor::clientData, HandlerDescriptor::conditionSet, BasicTaskScheduler0::fDelayQueue, fExceptionSet, BasicTaskScheduler0::fHandlers, BasicTaskScheduler0::fLastHandledSocketNum, fMaxNumSockets, fReadSet, fWriteSet, DelayQueue::handleAlarm(), HandlerDescriptor::handlerProc, iter, MILLION, MediaSubsessionIterator::next(), NULL, MediaSubsessionIterator::reset(), Timeval::seconds(), setBackgroundHandling(), SOCKET_EXCEPTION, SOCKET_READABLE, SOCKET_WRITABLE, HandlerDescriptor::socketNum, DelayQueue::timeToNextAlarm(), and Timeval::useconds().
00049 { 00050 fd_set readSet = fReadSet; // make a copy for this select() call 00051 fd_set writeSet = fWriteSet; // ditto 00052 fd_set exceptionSet = fExceptionSet; // ditto 00053 00054 DelayInterval const& timeToDelay = fDelayQueue.timeToNextAlarm(); 00055 struct timeval tv_timeToDelay; 00056 tv_timeToDelay.tv_sec = timeToDelay.seconds(); 00057 tv_timeToDelay.tv_usec = timeToDelay.useconds(); 00058 // Very large "tv_sec" values cause select() to fail. 00059 // Don't make it any larger than 1 million seconds (11.5 days) 00060 const long MAX_TV_SEC = MILLION; 00061 if (tv_timeToDelay.tv_sec > MAX_TV_SEC) { 00062 tv_timeToDelay.tv_sec = MAX_TV_SEC; 00063 } 00064 // Also check our "maxDelayTime" parameter (if it's > 0): 00065 if (maxDelayTime > 0 && 00066 (tv_timeToDelay.tv_sec > (long)maxDelayTime/MILLION || 00067 (tv_timeToDelay.tv_sec == (long)maxDelayTime/MILLION && 00068 tv_timeToDelay.tv_usec > (long)maxDelayTime%MILLION))) { 00069 tv_timeToDelay.tv_sec = maxDelayTime/MILLION; 00070 tv_timeToDelay.tv_usec = maxDelayTime%MILLION; 00071 } 00072 00073 int selectResult = select(fMaxNumSockets, &readSet, &writeSet, &exceptionSet, &tv_timeToDelay); 00074 if (selectResult < 0) { 00075 #if defined(__WIN32__) || defined(_WIN32) 00076 int err = WSAGetLastError(); 00077 // For some unknown reason, select() in Windoze sometimes fails with WSAEINVAL if 00078 // it was called with no entries set in "readSet". If this happens, ignore it: 00079 if (err == WSAEINVAL && readSet.fd_count == 0) { 00080 err = EINTR; 00081 // To stop this from happening again, create a dummy socket: 00082 int dummySocketNum = socket(AF_INET, SOCK_DGRAM, 0); 00083 FD_SET((unsigned)dummySocketNum, &fReadSet); 00084 FD_SET((unsigned)dummySocketNum, &fWriteSet); 00085 FD_SET((unsigned)dummySocketNum, &fExceptionSet); 00086 } 00087 if (err != EINTR) { 00088 #else 00089 if (errno != EINTR && errno != EAGAIN) { 00090 #endif 00091 // Unexpected error - treat this as fatal: 00092 #if !defined(_WIN32_WCE) 00093 perror("BasicTaskScheduler::SingleStep(): select() fails"); 00094 #endif 00095 abort(); 00096 } 00097 } 00098 00099 // Call the handler function for one readable socket: 00100 HandlerIterator iter(*fHandlers); 00101 HandlerDescriptor* handler; 00102 // To ensure forward progress through the handlers, begin past the last 00103 // socket number that we handled: 00104 if (fLastHandledSocketNum >= 0) { 00105 while ((handler = iter.next()) != NULL) { 00106 if (handler->socketNum == fLastHandledSocketNum) break; 00107 } 00108 if (handler == NULL) { 00109 fLastHandledSocketNum = -1; 00110 iter.reset(); // start from the beginning instead 00111 } 00112 } 00113 while ((handler = iter.next()) != NULL) { 00114 int sock = handler->socketNum; // alias 00115 int resultConditionSet = 0; 00116 if (FD_ISSET(sock, &readSet) && FD_ISSET(sock, &fReadSet)/*sanity check*/) resultConditionSet |= SOCKET_READABLE; 00117 if (FD_ISSET(sock, &writeSet) && FD_ISSET(sock, &fWriteSet)/*sanity check*/) resultConditionSet |= SOCKET_WRITABLE; 00118 if (FD_ISSET(sock, &exceptionSet) && FD_ISSET(sock, &fExceptionSet)/*sanity check*/) resultConditionSet |= SOCKET_EXCEPTION; 00119 if ((resultConditionSet&handler->conditionSet) != 0 && handler->handlerProc != NULL) { 00120 fLastHandledSocketNum = sock; 00121 // Note: we set "fLastHandledSocketNum" before calling the handler, 00122 // in case the handler calls "doEventLoop()" reentrantly. 00123 (*handler->handlerProc)(handler->clientData, resultConditionSet); 00124 break; 00125 } 00126 } 00127 if (handler == NULL && fLastHandledSocketNum >= 0) { 00128 // We didn't call a handler, but we didn't get to check all of them, 00129 // so try again from the beginning: 00130 iter.reset(); 00131 while ((handler = iter.next()) != NULL) { 00132 int sock = handler->socketNum; // alias 00133 int resultConditionSet = 0; 00134 if (FD_ISSET(sock, &readSet) && FD_ISSET(sock, &fReadSet)/*sanity check*/) resultConditionSet |= SOCKET_READABLE; 00135 if (FD_ISSET(sock, &writeSet) && FD_ISSET(sock, &fWriteSet)/*sanity check*/) resultConditionSet |= SOCKET_WRITABLE; 00136 if (FD_ISSET(sock, &exceptionSet) && FD_ISSET(sock, &fExceptionSet)/*sanity check*/) resultConditionSet |= SOCKET_EXCEPTION; 00137 if ((resultConditionSet&handler->conditionSet) != 0 && handler->handlerProc != NULL) { 00138 fLastHandledSocketNum = sock; 00139 // Note: we set "fLastHandledSocketNum" before calling the handler, 00140 // in case the handler calls "doEventLoop()" reentrantly. 00141 (*handler->handlerProc)(handler->clientData, resultConditionSet); 00142 break; 00143 } 00144 } 00145 if (handler == NULL) fLastHandledSocketNum = -1;//because we didn't call a handler 00146 } 00147 00148 // Also handle any delayed event that may have come due. (Note that we do this *after* calling a socket 00149 // handler, in case the delayed event handler modifies the set of readable sockets.) 00150 fDelayQueue.handleAlarm(); 00151 }
| void BasicTaskScheduler::setBackgroundHandling | ( | int | socketNum, | |
| int | conditionSet, | |||
| BackgroundHandlerProc * | handlerProc, | |||
| void * | clientData | |||
| ) | [protected, virtual] |
Definition at line 154 of file BasicTaskScheduler.cpp.
References HandlerSet::assignHandler(), HandlerSet::clearHandler(), fExceptionSet, BasicTaskScheduler0::fHandlers, fMaxNumSockets, fReadSet, fWriteSet, SOCKET_EXCEPTION, SOCKET_READABLE, and SOCKET_WRITABLE.
Referenced by SingleStep().
00154 { 00155 if (socketNum < 0) return; 00156 FD_CLR((unsigned)socketNum, &fReadSet); 00157 FD_CLR((unsigned)socketNum, &fWriteSet); 00158 FD_CLR((unsigned)socketNum, &fExceptionSet); 00159 if (conditionSet == 0) { 00160 fHandlers->clearHandler(socketNum); 00161 if (socketNum+1 == fMaxNumSockets) { 00162 --fMaxNumSockets; 00163 } 00164 } else { 00165 fHandlers->assignHandler(socketNum, conditionSet, handlerProc, clientData); 00166 if (socketNum+1 > fMaxNumSockets) { 00167 fMaxNumSockets = socketNum+1; 00168 } 00169 if (conditionSet&SOCKET_READABLE) FD_SET((unsigned)socketNum, &fReadSet); 00170 if (conditionSet&SOCKET_WRITABLE) FD_SET((unsigned)socketNum, &fWriteSet); 00171 if (conditionSet&SOCKET_EXCEPTION) FD_SET((unsigned)socketNum, &fExceptionSet); 00172 } 00173 }
| void BasicTaskScheduler::moveSocketHandling | ( | int | oldSocketNum, | |
| int | newSocketNum | |||
| ) | [protected, virtual] |
Implements TaskScheduler.
Definition at line 175 of file BasicTaskScheduler.cpp.
References fExceptionSet, BasicTaskScheduler0::fHandlers, fMaxNumSockets, fReadSet, fWriteSet, and HandlerSet::moveHandler().
00175 { 00176 if (oldSocketNum < 0 || newSocketNum < 0) return; // sanity check 00177 if (FD_ISSET(oldSocketNum, &fReadSet)) {FD_CLR((unsigned)oldSocketNum, &fReadSet); FD_SET((unsigned)newSocketNum, &fReadSet);} 00178 if (FD_ISSET(oldSocketNum, &fWriteSet)) {FD_CLR((unsigned)oldSocketNum, &fWriteSet); FD_SET((unsigned)newSocketNum, &fWriteSet);} 00179 if (FD_ISSET(oldSocketNum, &fExceptionSet)) {FD_CLR((unsigned)oldSocketNum, &fExceptionSet); FD_SET((unsigned)newSocketNum, &fExceptionSet);} 00180 fHandlers->moveHandler(oldSocketNum, newSocketNum); 00181 00182 if (oldSocketNum+1 == fMaxNumSockets) { 00183 --fMaxNumSockets; 00184 } 00185 if (newSocketNum+1 > fMaxNumSockets) { 00186 fMaxNumSockets = newSocketNum+1; 00187 } 00188 }
| TaskToken BasicTaskScheduler0::scheduleDelayedTask | ( | int64_t | microseconds, | |
| TaskFunc * | proc, | |||
| void * | clientData | |||
| ) | [virtual, inherited] |
Implements TaskScheduler.
Definition at line 55 of file BasicTaskScheduler0.cpp.
References DelayQueue::addEntry(), BasicTaskScheduler0::fDelayQueue, and DelayQueueEntry::token().
00057 { 00058 if (microseconds < 0) microseconds = 0; 00059 DelayInterval timeToDelay((long)(microseconds/1000000), (long)(microseconds%1000000)); 00060 AlarmHandler* alarmHandler = new AlarmHandler(proc, clientData, timeToDelay); 00061 fDelayQueue.addEntry(alarmHandler); 00062 00063 return (void*)(alarmHandler->token()); 00064 }
| void BasicTaskScheduler0::unscheduleDelayedTask | ( | TaskToken & | prevTask | ) | [virtual, inherited] |
Implements TaskScheduler.
Definition at line 66 of file BasicTaskScheduler0.cpp.
References BasicTaskScheduler0::fDelayQueue, NULL, and DelayQueue::removeEntry().
00066 { 00067 DelayQueueEntry* alarmHandler = fDelayQueue.removeEntry((long)prevTask); 00068 prevTask = NULL; 00069 delete alarmHandler; 00070 }
| void BasicTaskScheduler0::doEventLoop | ( | char * | watchVariable | ) | [virtual, inherited] |
Implements TaskScheduler.
Definition at line 72 of file BasicTaskScheduler0.cpp.
References NULL, and BasicTaskScheduler0::SingleStep().
00072 { 00073 // Repeatedly loop, handling readble sockets and timed events: 00074 while (1) { 00075 if (watchVariable != NULL && *watchVariable != 0) break; 00076 SingleStep(); 00077 } 00078 }
| void TaskScheduler::rescheduleDelayedTask | ( | TaskToken & | task, | |
| int64_t | microseconds, | |||
| TaskFunc * | proc, | |||
| void * | clientData | |||
| ) | [virtual, inherited] |
Definition at line 40 of file UsageEnvironment.cpp.
References TaskScheduler::scheduleDelayedTask(), and TaskScheduler::unscheduleDelayedTask().
Referenced by RTSPServer::RTSPClientSession::noteLiveness().
00042 { 00043 unscheduleDelayedTask(task); 00044 task = scheduleDelayedTask(microseconds, proc, clientData); 00045 }
| virtual void TaskScheduler::setBackgroundHandling | ( | int | socketNum, | |
| int | conditionSet, | |||
| BackgroundHandlerProc * | handlerProc, | |||
| void * | clientData | |||
| ) | [pure virtual, inherited] |
| void TaskScheduler::disableBackgroundHandling | ( | int | socketNum | ) | [inline, inherited] |
Definition at line 128 of file UsageEnvironment.hh.
References NULL, and TaskScheduler::setBackgroundHandling().
Referenced by RTSPClient::connectionHandler1(), RTSPClient::resetTCPSockets(), and TaskScheduler::turnOffBackgroundReadHandling().
00128 { setBackgroundHandling(socketNum, 0, NULL, NULL); }
| void TaskScheduler::turnOnBackgroundReadHandling | ( | int | socketNum, | |
| BackgroundHandlerProc * | handlerProc, | |||
| void * | clientData | |||
| ) | [inline, inherited] |
Definition at line 140 of file UsageEnvironment.hh.
References TaskScheduler::setBackgroundHandling(), and SOCKET_READABLE.
Referenced by ByteStreamFileSource::doGetNextFrame(), BasicUDPSource::doGetNextFrame(), RTSPOverHTTPServer::HTTPClientConnection::HTTPClientConnection(), SIPClient::invite1(), RTSPServer::RTSPClientSession::RTSPClientSession(), RTSPOverHTTPServer::RTSPOverHTTPServer(), and RTSPServer::RTSPServer().
00140 { 00141 setBackgroundHandling(socketNum, SOCKET_READABLE, handlerProc, clientData); 00142 }
| void TaskScheduler::turnOffBackgroundReadHandling | ( | int | socketNum | ) | [inline, inherited] |
Definition at line 143 of file UsageEnvironment.hh.
References TaskScheduler::disableBackgroundHandling().
Referenced by RTCPInstance::addStreamSocket(), Socket::changePort(), SocketDescriptor::deregisterRTPInterface(), ByteStreamFileSource::doStopGettingFrames(), BasicUDPSource::doStopGettingFrames(), SIPClient::invite1(), RTPInterface::stopNetworkReading(), SocketDescriptor::tcpReadHandler1(), BasicUDPSource::~BasicUDPSource(), ByteStreamFileSource::~ByteStreamFileSource(), RTSPOverHTTPServer::HTTPClientConnection::~HTTPClientConnection(), RTSPServer::RTSPClientSession::~RTSPClientSession(), and RTSPServer::~RTSPServer().
00143 { disableBackgroundHandling(socketNum); }
int BasicTaskScheduler::fMaxNumSockets [protected] |
Definition at line 65 of file BasicUsageEnvironment.hh.
Referenced by moveSocketHandling(), setBackgroundHandling(), and SingleStep().
fd_set BasicTaskScheduler::fReadSet [protected] |
Definition at line 66 of file BasicUsageEnvironment.hh.
Referenced by BasicTaskScheduler(), moveSocketHandling(), setBackgroundHandling(), and SingleStep().
fd_set BasicTaskScheduler::fWriteSet [protected] |
Definition at line 67 of file BasicUsageEnvironment.hh.
Referenced by BasicTaskScheduler(), moveSocketHandling(), setBackgroundHandling(), and SingleStep().
fd_set BasicTaskScheduler::fExceptionSet [protected] |
Definition at line 68 of file BasicUsageEnvironment.hh.
Referenced by BasicTaskScheduler(), moveSocketHandling(), setBackgroundHandling(), and SingleStep().
DelayQueue BasicTaskScheduler0::fDelayQueue [protected, inherited] |
Definition at line 94 of file BasicUsageEnvironment0.hh.
Referenced by BasicTaskScheduler0::scheduleDelayedTask(), SingleStep(), and BasicTaskScheduler0::unscheduleDelayedTask().
HandlerSet* BasicTaskScheduler0::fHandlers [protected, inherited] |
Definition at line 97 of file BasicUsageEnvironment0.hh.
Referenced by BasicTaskScheduler0::BasicTaskScheduler0(), moveSocketHandling(), setBackgroundHandling(), SingleStep(), and BasicTaskScheduler0::~BasicTaskScheduler0().
int BasicTaskScheduler0::fLastHandledSocketNum [protected, inherited] |
1.5.2