Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

PollThread.cc

Go to the documentation of this file.
00001 #ifndef PLATFORM_APERIOS
00002 #include "PollThread.h"
00003 #include <errno.h>
00004 #include <signal.h>
00005 
00006 //better to put this here instead of the header
00007 using namespace std; 
00008 
00009 void PollThread::start() {
00010   initialPoll=true;
00011   startTime.Set();
00012   Thread::start();
00013 }
00014 
00015 bool PollThread::poll() {
00016   unsigned int sleeptime=runloop();
00017   if(sleeptime==-1U)
00018     return false;
00019   period.Set(static_cast<long>(sleeptime));
00020   return true;
00021 }
00022 
00023 void PollThread::interrupted() {
00024   if(!initialPoll) {
00025     if(period-startTime.Age()<1L) {
00026       delay=0L;
00027     } else {
00028       while(!(period-startTime.Age()<1L))
00029         startTime-=period;
00030       startTime+=period;
00031       delay=period;
00032     }
00033   }
00034 }
00035 
00036 void * PollThread::run() {
00037   timespec sleepSpec,remainSpec;
00038   if(startTime.Age()<delay) {
00039     sleepSpec=delay-startTime.Age();
00040     while(nanosleep(&sleepSpec,&remainSpec)) {
00041       if(errno!=EINTR) {
00042         perror("PollThread::run(): initial nanosleep");
00043         break;
00044       }
00045       testCancel();
00046       //interrupted() may have changed delay to indicate remaining sleep time
00047       if(delay<1L || delay<startTime.Age())
00048         break;
00049       sleepSpec=delay-startTime.Age();
00050     }
00051   }
00052   testCancel();
00053   if(!poll())
00054     return returnValue;
00055   initialPoll=false;
00056   bool wasInterrupted=true; // need to add delay instead of period for the first time, same as if an interrupt occurred
00057   for(;;) {
00058     bool noSleep=false;
00059     if(TimeET(0,0)<period) {
00060       if(trackPollTime) {
00061         if(wasInterrupted) {
00062           if(delay<0L || startTime.Age()<delay) {}
00063           else
00064             startTime+=delay;
00065         } else {
00066           if(startTime.Age()<period) {}
00067           else
00068             startTime+=period;
00069         }
00070         //the idea with this part is that if we get behind, (because of poll() taking longer than period)
00071         // then we want to quick poll again as fast as we can to catch up, but we don't want to backlog
00072         // such that we'll be quick-calling multiple times once we do catch up
00073         if(period<startTime.Age()) {
00074           noSleep=true;
00075           while(period<startTime.Age())
00076             startTime+=period;
00077           startTime-=period; //back off one -- the amount we've overshot counts towards the next period
00078         }
00079         sleepSpec=period-startTime.Age();
00080       } else {
00081         sleepSpec=period;
00082         startTime.Set();
00083       }
00084       wasInterrupted=false;
00085       while(!noSleep && nanosleep(&sleepSpec,&remainSpec)) {
00086         wasInterrupted=true;
00087         if(errno!=EINTR) {
00088           perror("PollThread::run(): periodic nanosleep");
00089           break;
00090         }
00091         testCancel();
00092         //interrupted() should have changed delay and/or period to indicate remaining sleep time
00093         if(delay<1L || delay<startTime.Age())
00094           break;
00095         sleepSpec=delay-startTime.Age();
00096       }
00097     } else {
00098       startTime.Set();
00099     }
00100     testCancel();
00101     if(!poll())
00102       return returnValue;
00103   }
00104   // this return is just to satisfy warnings with silly compiler
00105   return returnValue; //never happens -- cancel or bad poll would exit
00106 }
00107 
00108 //void PollThread::cancelled() {
00109   //signal handlers are global, not per-thread, so if we reset the handler, then the next interrupt will cause the program to end :(
00110   //signal(SIGALRM,SIG_DFL);
00111 //}
00112 
00113 
00114 
00115 /*! @file
00116  * @brief 
00117  * @author Ethan Tira-Thompson (ejt) (Creator)
00118  *
00119  * $Author: ejt $
00120  * $Name: tekkotsu-4_0 $
00121  * $Revision: 1.14 $
00122  * $State: Exp $
00123  * $Date: 2007/10/12 16:55:04 $
00124  */
00125 #endif

Tekkotsu v4.0
Generated Thu Nov 22 00:54:55 2007 by Doxygen 1.5.4