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