00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "BasicUsageEnvironment.hh"
00022 #include "HandlerSet.hh"
00023 #include <stdio.h>
00024 #if defined(_QNX4)
00025 #include <sys/select.h>
00026 #include <unix.h>
00027 #endif
00028
00030
00031 BasicTaskScheduler* BasicTaskScheduler::createNew(unsigned maxSchedulerGranularity) {
00032 return new BasicTaskScheduler(maxSchedulerGranularity);
00033 }
00034
00035 BasicTaskScheduler::BasicTaskScheduler(unsigned maxSchedulerGranularity)
00036 : fMaxSchedulerGranularity(maxSchedulerGranularity), fMaxNumSockets(0) {
00037 FD_ZERO(&fReadSet);
00038 FD_ZERO(&fWriteSet);
00039 FD_ZERO(&fExceptionSet);
00040
00041 if (maxSchedulerGranularity > 0) schedulerTickTask();
00042 }
00043
00044 BasicTaskScheduler::~BasicTaskScheduler() {
00045 }
00046
00047 void BasicTaskScheduler::schedulerTickTask(void* clientData) {
00048 ((BasicTaskScheduler*)clientData)->schedulerTickTask();
00049 }
00050
00051 void BasicTaskScheduler::schedulerTickTask() {
00052 scheduleDelayedTask(fMaxSchedulerGranularity, schedulerTickTask, this);
00053 }
00054
00055 #ifndef MILLION
00056 #define MILLION 1000000
00057 #endif
00058
00059 void BasicTaskScheduler::SingleStep(unsigned maxDelayTime) {
00060 fd_set readSet = fReadSet;
00061 fd_set writeSet = fWriteSet;
00062 fd_set exceptionSet = fExceptionSet;
00063
00064 DelayInterval const& timeToDelay = fDelayQueue.timeToNextAlarm();
00065 struct timeval tv_timeToDelay;
00066 tv_timeToDelay.tv_sec = timeToDelay.seconds();
00067 tv_timeToDelay.tv_usec = timeToDelay.useconds();
00068
00069
00070 const long MAX_TV_SEC = MILLION;
00071 if (tv_timeToDelay.tv_sec > MAX_TV_SEC) {
00072 tv_timeToDelay.tv_sec = MAX_TV_SEC;
00073 }
00074
00075 if (maxDelayTime > 0 &&
00076 (tv_timeToDelay.tv_sec > (long)maxDelayTime/MILLION ||
00077 (tv_timeToDelay.tv_sec == (long)maxDelayTime/MILLION &&
00078 tv_timeToDelay.tv_usec > (long)maxDelayTime%MILLION))) {
00079 tv_timeToDelay.tv_sec = maxDelayTime/MILLION;
00080 tv_timeToDelay.tv_usec = maxDelayTime%MILLION;
00081 }
00082
00083 int selectResult = select(fMaxNumSockets, &readSet, &writeSet, &exceptionSet, &tv_timeToDelay);
00084 if (selectResult < 0) {
00085 #if defined(__WIN32__) || defined(_WIN32)
00086 int err = WSAGetLastError();
00087
00088
00089 if (err == WSAEINVAL && readSet.fd_count == 0) {
00090 err = EINTR;
00091
00092 int dummySocketNum = socket(AF_INET, SOCK_DGRAM, 0);
00093 FD_SET((unsigned)dummySocketNum, &fReadSet);
00094 }
00095 if (err != EINTR) {
00096 #else
00097 if (errno != EINTR && errno != EAGAIN) {
00098 #endif
00099
00100 #if !defined(_WIN32_WCE)
00101 perror("BasicTaskScheduler::SingleStep(): select() fails");
00102
00103
00104
00105 fprintf(stderr, "socket numbers used in the select() call:");
00106 for (int i = 0; i < 100; ++i) {
00107 if (FD_ISSET(i, &fReadSet) || FD_ISSET(i, &fWriteSet) || FD_ISSET(i, &fExceptionSet)) {
00108 fprintf(stderr, " %d(", i);
00109 if (FD_ISSET(i, &fReadSet)) fprintf(stderr, "r");
00110 if (FD_ISSET(i, &fWriteSet)) fprintf(stderr, "w");
00111 if (FD_ISSET(i, &fExceptionSet)) fprintf(stderr, "e");
00112 fprintf(stderr, ")");
00113 }
00114 }
00115 fprintf(stderr, "\n");
00116 #endif
00117 internalError();
00118 }
00119 }
00120
00121
00122 HandlerIterator iter(*fHandlers);
00123 HandlerDescriptor* handler;
00124
00125
00126 if (fLastHandledSocketNum >= 0) {
00127 while ((handler = iter.next()) != NULL) {
00128 if (handler->socketNum == fLastHandledSocketNum) break;
00129 }
00130 if (handler == NULL) {
00131 fLastHandledSocketNum = -1;
00132 iter.reset();
00133 }
00134 }
00135 while ((handler = iter.next()) != NULL) {
00136 int sock = handler->socketNum;
00137 int resultConditionSet = 0;
00138 if (FD_ISSET(sock, &readSet) && FD_ISSET(sock, &fReadSet)) resultConditionSet |= SOCKET_READABLE;
00139 if (FD_ISSET(sock, &writeSet) && FD_ISSET(sock, &fWriteSet)) resultConditionSet |= SOCKET_WRITABLE;
00140 if (FD_ISSET(sock, &exceptionSet) && FD_ISSET(sock, &fExceptionSet)) resultConditionSet |= SOCKET_EXCEPTION;
00141 if ((resultConditionSet&handler->conditionSet) != 0 && handler->handlerProc != NULL) {
00142 fLastHandledSocketNum = sock;
00143
00144
00145 (*handler->handlerProc)(handler->clientData, resultConditionSet);
00146 break;
00147 }
00148 }
00149 if (handler == NULL && fLastHandledSocketNum >= 0) {
00150
00151
00152 iter.reset();
00153 while ((handler = iter.next()) != NULL) {
00154 int sock = handler->socketNum;
00155 int resultConditionSet = 0;
00156 if (FD_ISSET(sock, &readSet) && FD_ISSET(sock, &fReadSet)) resultConditionSet |= SOCKET_READABLE;
00157 if (FD_ISSET(sock, &writeSet) && FD_ISSET(sock, &fWriteSet)) resultConditionSet |= SOCKET_WRITABLE;
00158 if (FD_ISSET(sock, &exceptionSet) && FD_ISSET(sock, &fExceptionSet)) resultConditionSet |= SOCKET_EXCEPTION;
00159 if ((resultConditionSet&handler->conditionSet) != 0 && handler->handlerProc != NULL) {
00160 fLastHandledSocketNum = sock;
00161
00162
00163 (*handler->handlerProc)(handler->clientData, resultConditionSet);
00164 break;
00165 }
00166 }
00167 if (handler == NULL) fLastHandledSocketNum = -1;
00168 }
00169
00170
00171
00172 if (fTriggersAwaitingHandling != 0) {
00173 if (fTriggersAwaitingHandling == fLastUsedTriggerMask) {
00174
00175 fTriggersAwaitingHandling = 0;
00176 if (fTriggeredEventHandlers[fLastUsedTriggerNum] != NULL) {
00177 (*fTriggeredEventHandlers[fLastUsedTriggerNum])(fTriggeredEventClientDatas[fLastUsedTriggerNum]);
00178 }
00179 } else {
00180
00181 unsigned i = fLastUsedTriggerNum;
00182 EventTriggerId mask = fLastUsedTriggerMask;
00183
00184 do {
00185 i = (i+1)%MAX_NUM_EVENT_TRIGGERS;
00186 mask >>= 1;
00187 if (mask == 0) mask = 0x80000000;
00188
00189 if ((fTriggersAwaitingHandling&mask) != 0) {
00190 fTriggersAwaitingHandling &=~ mask;
00191 if (fTriggeredEventHandlers[i] != NULL) {
00192 (*fTriggeredEventHandlers[i])(fTriggeredEventClientDatas[i]);
00193 }
00194
00195 fLastUsedTriggerMask = mask;
00196 fLastUsedTriggerNum = i;
00197 break;
00198 }
00199 } while (i != fLastUsedTriggerNum);
00200 }
00201 }
00202
00203
00204 fDelayQueue.handleAlarm();
00205 }
00206
00207 void BasicTaskScheduler
00208 ::setBackgroundHandling(int socketNum, int conditionSet, BackgroundHandlerProc* handlerProc, void* clientData) {
00209 if (socketNum < 0) return;
00210 FD_CLR((unsigned)socketNum, &fReadSet);
00211 FD_CLR((unsigned)socketNum, &fWriteSet);
00212 FD_CLR((unsigned)socketNum, &fExceptionSet);
00213 if (conditionSet == 0) {
00214 fHandlers->clearHandler(socketNum);
00215 if (socketNum+1 == fMaxNumSockets) {
00216 --fMaxNumSockets;
00217 }
00218 } else {
00219 fHandlers->assignHandler(socketNum, conditionSet, handlerProc, clientData);
00220 if (socketNum+1 > fMaxNumSockets) {
00221 fMaxNumSockets = socketNum+1;
00222 }
00223 if (conditionSet&SOCKET_READABLE) FD_SET((unsigned)socketNum, &fReadSet);
00224 if (conditionSet&SOCKET_WRITABLE) FD_SET((unsigned)socketNum, &fWriteSet);
00225 if (conditionSet&SOCKET_EXCEPTION) FD_SET((unsigned)socketNum, &fExceptionSet);
00226 }
00227 }
00228
00229 void BasicTaskScheduler::moveSocketHandling(int oldSocketNum, int newSocketNum) {
00230 if (oldSocketNum < 0 || newSocketNum < 0) return;
00231 if (FD_ISSET(oldSocketNum, &fReadSet)) {FD_CLR((unsigned)oldSocketNum, &fReadSet); FD_SET((unsigned)newSocketNum, &fReadSet);}
00232 if (FD_ISSET(oldSocketNum, &fWriteSet)) {FD_CLR((unsigned)oldSocketNum, &fWriteSet); FD_SET((unsigned)newSocketNum, &fWriteSet);}
00233 if (FD_ISSET(oldSocketNum, &fExceptionSet)) {FD_CLR((unsigned)oldSocketNum, &fExceptionSet); FD_SET((unsigned)newSocketNum, &fExceptionSet);}
00234 fHandlers->moveHandler(oldSocketNum, newSocketNum);
00235
00236 if (oldSocketNum+1 == fMaxNumSockets) {
00237 --fMaxNumSockets;
00238 }
00239 if (newSocketNum+1 > fMaxNumSockets) {
00240 fMaxNumSockets = newSocketNum+1;
00241 }
00242 }