00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef IMN_PIM
00022 #include "BasicUsageEnvironment.hh"
00023 #include "HandlerSet.hh"
00024 #include <stdio.h>
00025 #if defined(_QNX4)
00026 #include <sys/select.h>
00027 #include <unix.h>
00028 #endif
00029
00031
00032 BasicTaskScheduler* BasicTaskScheduler::createNew() {
00033 return new BasicTaskScheduler();
00034 }
00035
00036 BasicTaskScheduler::BasicTaskScheduler()
00037 : fMaxNumSockets(0) {
00038 FD_ZERO(&fReadSet);
00039 }
00040
00041 BasicTaskScheduler::~BasicTaskScheduler() {
00042 }
00043
00044 #ifndef MILLION
00045 #define MILLION 1000000
00046 #endif
00047
00048 void BasicTaskScheduler::SingleStep(unsigned maxDelayTime) {
00049 fd_set readSet = fReadSet;
00050
00051 DelayInterval const& timeToDelay = fDelayQueue.timeToNextAlarm();
00052 struct timeval tv_timeToDelay;
00053 tv_timeToDelay.tv_sec = timeToDelay.seconds();
00054 tv_timeToDelay.tv_usec = timeToDelay.useconds();
00055
00056
00057 const long MAX_TV_SEC = MILLION;
00058 if (tv_timeToDelay.tv_sec > MAX_TV_SEC) {
00059 tv_timeToDelay.tv_sec = MAX_TV_SEC;
00060 }
00061
00062 if (maxDelayTime > 0 &&
00063 (tv_timeToDelay.tv_sec > (long)maxDelayTime/MILLION ||
00064 (tv_timeToDelay.tv_sec == (long)maxDelayTime/MILLION &&
00065 tv_timeToDelay.tv_usec > (long)maxDelayTime%MILLION))) {
00066 tv_timeToDelay.tv_sec = maxDelayTime/MILLION;
00067 tv_timeToDelay.tv_usec = maxDelayTime%MILLION;
00068 }
00069
00070 int selectResult = select(fMaxNumSockets, &readSet, NULL, NULL,
00071 &tv_timeToDelay);
00072 if (selectResult < 0) {
00073 #if defined(__WIN32__) || defined(_WIN32)
00074 int err = WSAGetLastError();
00075
00076
00077 if (err == WSAEINVAL && readSet.fd_count == 0) {
00078 err = 0;
00079
00080 int dummySocketNum = socket(AF_INET, SOCK_DGRAM, 0);
00081 FD_SET((unsigned)dummySocketNum, &fReadSet);
00082 }
00083 if (err != 0) {
00084 #else
00085 if (errno != EINTR && errno != EAGAIN) {
00086 #endif
00087
00088 #if !defined(_WIN32_WCE)
00089 perror("BasicTaskScheduler::SingleStep(): select() fails");
00090 #endif
00091 exit(0);
00092 }
00093 }
00094
00095
00096 fDelayQueue.handleAlarm();
00097
00098
00099 HandlerIterator iter(*fReadHandlers);
00100 HandlerDescriptor* handler;
00101
00102
00103 if (fLastHandledSocketNum >= 0) {
00104 while ((handler = iter.next()) != NULL) {
00105 if (handler->socketNum == fLastHandledSocketNum) break;
00106 }
00107 if (handler == NULL) {
00108 fLastHandledSocketNum = -1;
00109 iter.reset();
00110 }
00111 }
00112 while ((handler = iter.next()) != NULL) {
00113 if (FD_ISSET(handler->socketNum, &readSet) &&
00114 FD_ISSET(handler->socketNum, &fReadSet) &&
00115 handler->handlerProc != NULL) {
00116 fLastHandledSocketNum = handler->socketNum;
00117
00118
00119 (*handler->handlerProc)(handler->clientData, SOCKET_READABLE);
00120 break;
00121 }
00122 }
00123 if (handler == NULL && fLastHandledSocketNum >= 0) {
00124
00125
00126 iter.reset();
00127 while ((handler = iter.next()) != NULL) {
00128 if (FD_ISSET(handler->socketNum, &readSet) &&
00129 FD_ISSET(handler->socketNum, &fReadSet) &&
00130 handler->handlerProc != NULL) {
00131 fLastHandledSocketNum = handler->socketNum;
00132
00133
00134 (*handler->handlerProc)(handler->clientData, SOCKET_READABLE);
00135 break;
00136 }
00137 }
00138 if (handler == NULL) fLastHandledSocketNum = -1;
00139 }
00140 }
00141
00142 void BasicTaskScheduler::turnOnBackgroundReadHandling(int socketNum,
00143 BackgroundHandlerProc* handlerProc,
00144 void* clientData) {
00145 if (socketNum < 0) return;
00146 FD_SET((unsigned)socketNum, &fReadSet);
00147 fReadHandlers->assignHandler(socketNum, handlerProc, clientData);
00148
00149 if (socketNum+1 > fMaxNumSockets) {
00150 fMaxNumSockets = socketNum+1;
00151 }
00152 }
00153
00154 void BasicTaskScheduler::turnOffBackgroundReadHandling(int socketNum) {
00155 if (socketNum < 0) return;
00156 FD_CLR((unsigned)socketNum, &fReadSet);
00157 fReadHandlers->removeHandler(socketNum);
00158
00159 if (socketNum+1 == fMaxNumSockets) {
00160 --fMaxNumSockets;
00161 }
00162 }
00163 #endif
00164