BasicUsageEnvironment/BasicTaskScheduler0.cpp

Go to the documentation of this file.
00001 /**********
00002 This library is free software; you can redistribute it and/or modify it under
00003 the terms of the GNU Lesser General Public License as published by the
00004 Free Software Foundation; either version 2.1 of the License, or (at your
00005 option) any later version. (See <http://www.gnu.org/copyleft/lesser.html>.)
00006 
00007 This library is distributed in the hope that it will be useful, but WITHOUT
00008 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00009 FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
00010 more details.
00011 
00012 You should have received a copy of the GNU Lesser General Public License
00013 along with this library; if not, write to the Free Software Foundation, Inc.,
00014 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
00015 **********/
00016 // Copyright (c) 1996-2008 Live Networks, Inc.  All rights reserved.
00017 // Basic Usage Environment: for a simple, non-scripted, console application
00018 // Implementation
00019 
00020 #include "BasicUsageEnvironment0.hh"
00021 #include "HandlerSet.hh"
00022 
00025 
00026 class AlarmHandler: public DelayQueueEntry {
00027 public:
00028   AlarmHandler(TaskFunc* proc, void* clientData, DelayInterval timeToDelay)
00029     : DelayQueueEntry(timeToDelay), fProc(proc), fClientData(clientData) {
00030   }
00031 
00032 private: // redefined virtual functions
00033   virtual void handleTimeout() {
00034     (*fProc)(fClientData);
00035     DelayQueueEntry::handleTimeout();
00036   }
00037 
00038 private:
00039   TaskFunc* fProc;
00040   void* fClientData;
00041 };
00042 
00043 
00045 
00046 BasicTaskScheduler0::BasicTaskScheduler0()
00047   : fLastHandledSocketNum(-1) {
00048   fReadHandlers = new HandlerSet;
00049 }
00050 
00051 BasicTaskScheduler0::~BasicTaskScheduler0() {
00052   delete fReadHandlers;
00053 }
00054 
00055 TaskToken BasicTaskScheduler0::scheduleDelayedTask(int64_t microseconds,
00056                                                  TaskFunc* proc,
00057                                                  void* clientData) {
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 }
00065 
00066 void BasicTaskScheduler0::unscheduleDelayedTask(TaskToken& prevTask) {
00067   DelayQueueEntry* alarmHandler = fDelayQueue.removeEntry((long)prevTask);
00068   prevTask = NULL;
00069   delete alarmHandler;
00070 }
00071 
00072 void BasicTaskScheduler0::doEventLoop(char* watchVariable) {
00073   // Repeatedly loop, handling readble sockets and timed events:
00074   while (1) {
00075     if (watchVariable != NULL && *watchVariable != 0) break;
00076     SingleStep();
00077   }
00078 }
00079 
00080 
00082 
00083 HandlerDescriptor::HandlerDescriptor(HandlerDescriptor* nextHandler) {
00084   // Link this descriptor into a doubly-linked list:
00085   if (nextHandler == this) { // initialization
00086     fNextHandler = fPrevHandler = this;
00087   } else {
00088     fNextHandler = nextHandler;
00089     fPrevHandler = nextHandler->fPrevHandler;
00090     nextHandler->fPrevHandler = this;
00091     fPrevHandler->fNextHandler = this;
00092   }
00093 }
00094 
00095 HandlerDescriptor::~HandlerDescriptor() {
00096   // Unlink this descriptor from a doubly-linked list:
00097   fNextHandler->fPrevHandler = fPrevHandler;
00098   fPrevHandler->fNextHandler = fNextHandler;
00099 }
00100 
00101 HandlerSet::HandlerSet()
00102   : fHandlers(&fHandlers) {
00103   fHandlers.socketNum = -1; // shouldn't ever get looked at, but in case...
00104 }
00105 
00106 HandlerSet::~HandlerSet() {
00107   // Delete each handler descriptor:
00108   while (fHandlers.fNextHandler != &fHandlers) {
00109     delete fHandlers.fNextHandler; // changes fHandlers->fNextHandler
00110   }
00111 }
00112 
00113 void HandlerSet
00114 ::assignHandler(int socketNum,
00115                 TaskScheduler::BackgroundHandlerProc* handlerProc,
00116                 void* clientData) {
00117   // First, see if there's already a handler for this socket:
00118   HandlerDescriptor* handler;
00119   HandlerIterator iter(*this);
00120   while ((handler = iter.next()) != NULL) {
00121     if (handler->socketNum == socketNum) break;
00122   }
00123   if (handler == NULL) { // No existing handler, so create a new descr:
00124     handler = new HandlerDescriptor(fHandlers.fNextHandler);
00125     handler->socketNum = socketNum;
00126   }
00127 
00128   handler->handlerProc = handlerProc;
00129   handler->clientData = clientData;
00130 }
00131 
00132 void HandlerSet::removeHandler(int socketNum) {
00133   HandlerDescriptor* handler;
00134   HandlerIterator iter(*this);
00135   while ((handler = iter.next()) != NULL) {
00136     if (handler->socketNum == socketNum) {
00137       delete handler;
00138       break;
00139     }
00140   }
00141 }
00142 
00143 HandlerIterator::HandlerIterator(HandlerSet& handlerSet)
00144   : fOurSet(handlerSet) {
00145   reset();
00146 }
00147 
00148 HandlerIterator::~HandlerIterator() {
00149 }
00150 
00151 void HandlerIterator::reset() {
00152   fNextPtr = fOurSet.fHandlers.fNextHandler;
00153 }
00154 
00155 HandlerDescriptor* HandlerIterator::next() {
00156   HandlerDescriptor* result = fNextPtr;
00157   if (result == &fOurSet.fHandlers) { // no more
00158     result = NULL;
00159   } else {
00160     fNextPtr = fNextPtr->fNextHandler;
00161   }
00162 
00163   return result;
00164 }

Generated on Tue Oct 7 15:38:08 2008 for live by  doxygen 1.5.2