|
reSIProcate/rutil
9694
|
00001 #include <stdlib.h> 00002 #include "rutil/Poll.hxx" 00003 00004 using namespace resip; 00005 using namespace std; 00006 00007 #if !defined(RESIP_POLL_IMPL_POLL) && !defined(RESIP_POLL_IMPL_SELECT) && !defined(RESIP_POLL_EPOLL) 00008 #error "Define one of RESIP_POLL_IMPL_POLL, RESIP_POLL_IMPL_SELECT, or RESIP_POLL_EPOLL." 00009 #endif 00010 00012 00013 //constructor 00014 Poll::FDEntry::FDEntry(Poll* poll, 00015 bool isTransport, 00016 int/*FD*/ fd) : 00017 _poll(poll), 00018 _fd(fd), 00019 _stateBitMask(isTransport ? Poll::FDEntry::rsbmIsTransport : 0), 00020 _index((unsigned short)poll->_fdEntryVector.size()) 00021 { 00022 _poll->_fdEntryVector.push_back(this); 00023 #ifdef RESIP_POLL_IMPL_POLL 00024 pollfd pollFD; 00025 pollFD.fd = fd; 00026 pollFD.events = POLLIN; 00027 _poll->_pollFDVector.push_back(pollFD); 00028 #endif 00029 #ifdef RESIP_POLL_IMPL_SELECT 00030 if (_fd >= _poll->_maxFDPlus1) 00031 { 00032 _poll->_maxFDPlus1 = _fd + 1; 00033 } 00034 FD_SET(_fd, &(_poll->_readFDSet)); 00035 #endif 00036 #ifdef RESIP_POLL_EXTERN 00037 _poll->_fdEntryMap.insert(std::pair<int/*FD*/, Poll::FDEntry *>(_fd, this)); 00038 #endif 00039 } 00040 00041 //destructor 00042 Poll::FDEntry::~FDEntry() 00043 { 00044 vector<Poll::FDEntry *> &fdEntryVector = _poll->_fdEntryVector; 00045 Poll::FDEntry *lastFDEntry = fdEntryVector[fdEntryVector.size() - 1]; 00046 lastFDEntry->_index = _index; 00047 fdEntryVector[_index] = lastFDEntry; 00048 fdEntryVector.pop_back(); 00049 #ifdef RESIP_POLL_IMPL_POLL 00050 vector<pollfd> &pollFDVector = _poll->_pollFDVector; 00051 pollFDVector[_index] = pollFDVector[pollFDVector.size() - 1]; 00052 pollFDVector.pop_back(); 00053 #endif 00054 #ifdef RESIP_POLL_IMPL_SELECT 00055 FD_CLR(_fd, &(_poll->_readFDSet)); 00056 FD_CLR(_fd, &(_poll->_writeFDSet)); 00057 #endif 00058 #ifdef RESIP_POLL_EXTERN 00059 _poll->_fdEntryMap.erase(_fd); 00060 #endif 00061 } 00062 00063 void 00064 Poll::FDEntry::clearFDState() 00065 { 00066 _stateBitMask &= ~Poll::FDEntry::fdsbmAll; 00067 } 00068 00069 void 00070 Poll::FDEntry::setIsWritePending(bool isWritePending) 00071 { 00072 if (isWritePending) 00073 { 00074 _stateBitMask |= Poll::FDEntry::rsbmIsWritePending; 00075 #ifdef RESIP_POLL_IMPL_POLL 00076 _poll->_pollFDVector[_index].events |= Poll::FDEntry::fdsbmWritable; 00077 #endif 00078 #ifdef RESIP_POLL_IMPL_SELECT 00079 FD_SET(_fd, &(_poll->_writeFDSet)); 00080 #endif 00081 } else 00082 { 00083 _stateBitMask &= ~Poll::FDEntry::rsbmIsWritePending; 00084 #ifdef RESIP_POLL_IMPL_POLL 00085 _poll->_pollFDVector[_index].events &= ~Poll::FDEntry::fdsbmWritable; 00086 #endif 00087 #ifdef RESIP_POLL_IMPL_SELECT 00088 FD_CLR(_fd, &(_poll->_writeFDSet)); 00089 #endif 00090 } 00091 } 00092 00093 //static 00094 int 00095 Poll::FDEntry::compare(const Poll::FDEntry * leftFDEntry, 00096 const Poll::FDEntry * rightFDEntry) 00097 { 00098 return (leftFDEntry->getFD() - rightFDEntry->getFD()); 00099 } 00100 00102 00103 //static 00104 int 00105 Poll::findFDInWaitResult(int/*FD*/ fd, 00106 const vector<Poll::FDEntry *> & waitResult) 00107 { 00108 unsigned int lowIndex = 0; 00109 unsigned int highIndex = (unsigned int)waitResult.size(); 00110 while (lowIndex + 1 < highIndex) 00111 { 00112 // The goal fd is in waitResult in the range [lowIndex, highIndex[. 00113 unsigned int midIndex = (lowIndex + highIndex) / 2; 00114 if (waitResult[midIndex]->_fd > fd) 00115 { 00116 highIndex = midIndex - 1; 00117 } 00118 else 00119 { 00120 lowIndex = midIndex; 00121 } 00122 }//while 00123 return lowIndex; 00124 } 00125 00126 //constructor 00127 Poll::Poll() 00128 #ifdef RESIP_POLL_IMPL_SELECT 00129 : 00130 _maxFDPlus1(0) 00131 #endif 00132 { 00133 #ifdef RESIP_POLL_IMPL_SELECT 00134 FD_ZERO(&_readFDSet); 00135 FD_ZERO(&_writeFDSet); 00136 #endif 00137 } 00138 00139 //destructor 00140 Poll::~Poll() 00141 { 00142 } 00143 00144 #ifdef RESIP_POLL_EXTERN // { 00145 00146 const vector<Poll::FDEntry *> & 00147 Poll::beforeExternWait() 00148 { 00149 _waitResult.clear(); 00150 return _fdEntryVector; 00151 } 00152 00153 bool 00154 Poll::setEntryFDStateForExternWait(int/*FD*/ fd, 00155 Poll::FDEntry::StateBitMask fdStateBitMask) 00156 { 00157 map<int/*FD*/, Poll::FDEntry *>::const_iterator fdEntryIterator = 00158 _fdEntryMap.find(fd); 00159 bool isFDInPoll = (fdEntryIterator != _fdEntryMap.end()); 00160 if (isFDInPoll) 00161 { 00162 Poll::FDEntry *fdEntry = fdEntryIterator->second; 00163 fdEntry->_stateBitMask |= fdStateBitMask & Poll::FDEntry::fdsbmAll; 00164 _waitResult.push_back(fdEntry); 00165 } 00166 return isFDInPoll; 00167 } 00168 00169 const vector<Poll::FDEntry *> & 00170 Poll::afterExternWait() 00171 { 00172 return _waitResult; 00173 } 00174 00175 #else //!defined(RESIP_POLL_EXTERN) } { 00176 00177 const vector<Poll::FDEntry *> & 00178 Poll::wait(int timeoutMilliSeconds) 00179 { 00180 _waitResult.clear(); 00181 #ifdef RESIP_POLL_IMPL_POLL 00182 pollfd *pollFDArray = &(_pollFDVector.front()); 00183 int numReadyFDs = poll(pollFDArray, 00184 _pollFDVector.size(), 00185 timeoutMilliSeconds); 00186 if (numReadyFDs < 0) 00187 { 00189 } 00190 for (unsigned short index = 0; numReadyFDs > 0; ++index) 00191 { 00192 int revents = pollFDArray[index].revents; 00193 if (revents) 00194 { 00195 Poll::FDEntry *fdEntry = _fdEntryVector[index]; 00196 fdEntry->_stateBitMask |= revents; 00197 _waitResult.push_back(fdEntry); 00198 --numReadyFDs; 00199 } 00200 }//for 00201 qsort(&(_waitResult.front()), 00202 _waitResult.size(), 00203 sizeof(Poll::FDEntry *), 00204 reinterpret_cast<int(*)(const void *, 00205 const void *)>(&Poll::FDEntry::compare)); 00206 #endif 00207 #ifdef RESIP_POLL_IMPL_SELECT 00208 fd_set readableFDSet = _readFDSet; 00209 fd_set writableFDSet = _writeFDSet; 00210 fd_set errorFDSet = _readFDSet; 00211 timeval timeoutTimeVal; 00212 timeoutTimeVal.tv_sec = timeoutMilliSeconds / 1000; 00213 timeoutTimeVal.tv_usec = 1000 * (timeoutMilliSeconds % 1000); 00214 int numReadyFDs = select(_maxFDPlus1, 00215 &readableFDSet, 00216 &writableFDSet, 00217 &errorFDSet, 00218 &timeoutTimeVal); 00219 if (numReadyFDs < 0) 00220 { 00222 } 00223 for (unsigned short index = 0; numReadyFDs > 0; ++index) 00224 { 00225 Poll::FDEntry *fdEntry = _fdEntryVector[index]; 00226 bool isFDReadable = FD_ISSET(fdEntry->_fd, &readableFDSet); 00227 bool isFDWritable = FD_ISSET(fdEntry->_fd, &writableFDSet); 00228 bool isFDError = FD_ISSET(fdEntry->_fd, &errorFDSet); 00229 if (isFDReadable || isFDWritable || isFDError) 00230 { 00231 if (isFDReadable) 00232 { 00233 fdEntry->_stateBitMask |= Poll::FDEntry::fdsbmReadable; 00234 } 00235 if (isFDWritable) 00236 { 00237 fdEntry->_stateBitMask |= Poll::FDEntry::fdsbmWritable; 00238 } 00239 if (isFDError) 00240 { 00241 fdEntry->_stateBitMask |= Poll::FDEntry::fdsbmError; 00242 } 00243 _waitResult.push_back(fdEntry); 00244 --numReadyFDs; 00245 } 00246 }//for 00247 #endif 00248 return _waitResult; 00249 } 00250 00251 #endif //!defined(RESIP_POLL_EXTERN) } 00252 00253 /* ==================================================================== 00254 * The Vovida Software License, Version 1.0 00255 * 00256 * Copyright (c) 2000-2005 Jacob Butcher 00257 * 00258 * Redistribution and use in source and binary forms, with or without 00259 * modification, are permitted provided that the following conditions 00260 * are met: 00261 * 00262 * 1. Redistributions of source code must retain the above copyright 00263 * notice, this list of conditions and the following disclaimer. 00264 * 00265 * 2. Redistributions in binary form must reproduce the above copyright 00266 * notice, this list of conditions and the following disclaimer in 00267 * the documentation and/or other materials provided with the 00268 * distribution. 00269 * 00270 * 3. The names "VOCAL", "Vovida Open Communication Application Library", 00271 * and "Vovida Open Communication Application Library (VOCAL)" must 00272 * not be used to endorse or promote products derived from this 00273 * software without prior written permission. For written 00274 * permission, please contact vocal@vovida.org. 00275 * 00276 * 4. Products derived from this software may not be called "VOCAL", nor 00277 * may "VOCAL" appear in their name, without prior written 00278 * permission of Vovida Networks, Inc. 00279 * 00280 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED 00281 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00282 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND 00283 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA 00284 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES 00285 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, 00286 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00287 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00288 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 00289 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00290 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 00291 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 00292 * DAMAGE. 00293 * 00294 */
1.7.5.1