BasicTaskScheduler Class Reference

#include <BasicUsageEnvironment.hh>

Inheritance diagram for BasicTaskScheduler:

Inheritance graph
[legend]
Collaboration diagram for BasicTaskScheduler:

Collaboration graph
[legend]

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 BasicTaskSchedulercreateNew ()

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
HandlerSetfHandlers
int fLastHandledSocketNum

Detailed Description

Definition at line 47 of file BasicUsageEnvironment.hh.


Member Typedef Documentation

typedef void TaskScheduler::BackgroundHandlerProc(void *clientData, int mask) [inherited]

Definition at line 121 of file UsageEnvironment.hh.


Constructor & Destructor Documentation

BasicTaskScheduler::~BasicTaskScheduler (  )  [virtual]

Definition at line 42 of file BasicTaskScheduler.cpp.

00042                                         {
00043 }

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 }


Member Function Documentation

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]

Referenced by RTSPClient::connectionHandler1(), RTSPClient::connectToServer(), TaskScheduler::disableBackgroundHandling(), RTSPClient::openConnection(), and TaskScheduler::turnOnBackgroundReadHandling().

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); }


Field Documentation

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]

Definition at line 98 of file BasicUsageEnvironment0.hh.

Referenced by SingleStep().


The documentation for this class was generated from the following files:
Generated on Fri Sep 3 02:37:09 2010 for live by  doxygen 1.5.2