|
reSIProcate/rutil
9694
|
00001 #if !defined(RESIP_POLL_HXX) 00002 #define RESIP_POLL_HXX 00003 00004 // One of the following macros must be defined: 00005 //#define RESIP_POLL_IMPL_POLL 00006 #define RESIP_POLL_IMPL_SELECT 00007 //#define RESIP_POLL_IMPL_EPOLL // Not yet implemented. 00008 00009 /* 00010 Define this macro to support applications that must call system call "poll" 00011 or its ilk themselves rather than calling method "Poll::wait". 00012 */ 00013 #define RESIP_POLL_EXTERN 00014 00015 #include <vector> 00016 00017 #ifdef RESIP_POLL_IMPL_POLL 00018 # include <sys/poll.h> 00019 #endif 00020 00021 #ifdef RESIP_POLL_IMPL_SELECT 00022 # ifdef WIN32 00023 # include <winsock2.h> 00024 # else 00025 # include <sys/time.h> 00026 # include <sys/types.h> 00027 # include <unistd.h> 00028 # endif // WIN32 00029 #endif // RESIP_POLL_IMPL_SELECT 00030 00031 #ifdef RESIP_POLL_EXTERN 00032 # include <map> 00033 #endif // RESI 00034 00035 namespace resip { 00036 00038 00051 class Poll { 00052 00053 public: 00054 00055 class FDEntry { 00056 00057 friend class Poll; 00058 00059 public: 00060 00061 typedef unsigned short StateBitMask; // FDStateBitMask | ResipStateBitMask. 00062 enum FDStateBitMaskEnum { 00063 fdsbmReadable = 0x0001, // (POLLIN) 00064 fdsbmWritable = 0x0004, // (POLLOUT) 00065 fdsbmError = 0x0008, // (POLLERR) 00066 fdsbmAll = Poll::FDEntry::fdsbmReadable | 00067 Poll::FDEntry::fdsbmWritable | 00068 Poll::FDEntry::fdsbmError 00069 }; 00070 typedef StateBitMask FDStateBitMask; 00071 enum ResipStateBitMaskEnum { 00072 rsbmIsTransport = 0x0040, 00073 rsbmIsWritePending = 0x0080 00074 }; 00075 typedef StateBitMask ResipStateBitMask; 00076 00077 private: 00078 00079 static 00080 int 00081 compare(const Poll::FDEntry * leftFDEntry, 00082 const Poll::FDEntry * rightFDEntry); 00083 00084 // Fields: 00085 Poll * _poll; 00086 int/*FD*/ _fd; 00087 Poll::FDEntry::StateBitMask _stateBitMask; 00088 unsigned short _index; // Within "_poll->_fdEntryVector". 00089 00090 public: 00091 00092 //constructor 00093 FDEntry(Poll * poll, 00094 bool isTransport, 00095 int/*FD*/ fd); 00096 00097 //destructor 00098 virtual ~FDEntry(); 00099 00100 inline 00101 int//FD 00102 getFD() const 00103 { 00104 return _fd; 00105 } 00106 00107 inline 00108 Poll::FDEntry::StateBitMask 00109 getStateBitMask() const 00110 { 00111 return _stateBitMask; 00112 } 00113 00114 void 00115 clearFDState(); 00116 00117 protected: 00118 00119 void 00120 setIsWritePending(bool isWritePending); 00121 00122 virtual void doRead() {}; 00123 virtual void doWrite() {}; 00124 virtual void doError() {}; 00125 00126 private: 00127 00128 // Copy constructor: declared but not defined 00129 FDEntry(const Poll::FDEntry & from); 00130 00131 // Assignment: declared but not defined 00132 Poll::FDEntry & 00133 operator=(const Poll::FDEntry & from); 00134 00135 }; 00136 friend class Poll::FDEntry; 00137 00138 private: 00139 00140 // Fields: 00141 std::vector<Poll::FDEntry *> _fdEntryVector; 00142 #ifdef RESIP_POLL_IMPL_POLL 00143 std::vector<pollfd> _pollFDVector; 00144 #endif 00145 #ifdef RESIP_POLL_IMPL_SELECT 00146 int/*FD*/ _maxFDPlus1; 00147 fd_set _readFDSet; 00148 fd_set _writeFDSet; 00149 #endif 00150 #ifdef RESIP_POLL_EXTERN 00151 std::map<int/*FD*/, Poll::FDEntry *> _fdEntryMap; 00152 #endif 00153 std::vector<Poll::FDEntry *> _waitResult; 00154 00155 public: 00156 00157 /* 00158 "waitResult" is the result of method "wait" or "afterExternWait". 00159 Returns the index of the entry with the smallest file descriptor >= "fd" in 00160 "waitResult", or "waitResult.size()" if none exists. 00161 */ 00162 static 00163 int 00164 findFDInWaitResult(int/*FD*/ fd, 00165 const std::vector<Poll::FDEntry *> & waitResult); 00166 00167 //constructor 00168 Poll(); 00169 00170 //destructor 00171 ~Poll(); 00172 00173 #ifdef RESIP_POLL_EXTERN // { 00174 00175 // The result is the set of entries in this poll object. 00176 const std::vector<Poll::FDEntry *> & 00177 beforeExternWait(); 00178 00179 /* 00180 If "fd" has no entry in this poll object, ignore it and return false. 00181 Otherwise, set the entry's FD state from "fdStateBitMask" and return true. 00182 If the same "fd" is passed in multiple times, the "fdStateBitMask" are 00183 or-ed together. 00184 */ 00185 bool 00186 setEntryFDStateForExternWait(int/*FD*/ fd, 00187 Poll::FDEntry::StateBitMask fdStateBitMask); 00188 00189 // The result is identical to that of method "wait". 00190 const std::vector<Poll::FDEntry *> & 00191 afterExternWait(); 00192 00193 #else //!defined(RESIP_POLL_EXTERN) } { 00194 00195 /* 00196 Wait for I/O on any of this poll object's entry's file descriptors. 00197 More precisely, wait for the file descriptor of any entry with a pending 00198 write to be writable or for any entry's file descriptor to have readable 00199 input or an error. 00200 If "timeoutMilliSeconds" is negative, it means wait indefinitely, otherwise 00201 it indicates the maximum period to wait. 00202 The result is an array of the entries for the file descriptors that are 00203 readable, writable, or error, as specified by each entry's FD state. 00204 The result contains no duplicates and is sorted by file descriptor. 00205 (To service file descriptors with round-robin prioritization, remember the 00206 last file descriptor serviced and use method "Poll::findFDInWaitResult" to 00207 find the index in the result array of the highest priority entry.) 00208 The result is valid until the next call to this method, method 00209 "beforeExternWait", or the destructor. 00210 At some point before then, for each entry in the result, method 00211 "Poll::FDEntry::clearFDState" must be called. 00212 */ 00213 const std::vector<Poll::FDEntry *> & 00214 wait(int timeoutMilliSeconds); 00215 00216 #endif //!defined(RESIP_POLL_EXTERN) } 00217 00218 private: 00219 00220 // Copy constructor: declared but not defined 00221 Poll(const Poll & from); 00222 00223 // Assignment: declared but not defined 00224 Poll & 00225 operator=(const Poll & from); 00226 00227 }; 00228 00230 00231 } // namespace resip 00232 00233 #endif //!defined(RESIP_POLL_HXX) 00234 00235 /* ==================================================================== 00236 * The Vovida Software License, Version 1.0 00237 * 00238 * Copyright (c) 2000-2005 Jacob Butcher 00239 * 00240 * Redistribution and use in source and binary forms, with or without 00241 * modification, are permitted provided that the following conditions 00242 * are met: 00243 * 00244 * 1. Redistributions of source code must retain the above copyright 00245 * notice, this list of conditions and the following disclaimer. 00246 * 00247 * 2. Redistributions in binary form must reproduce the above copyright 00248 * notice, this list of conditions and the following disclaimer in 00249 * the documentation and/or other materials provided with the 00250 * distribution. 00251 * 00252 * 3. The names "VOCAL", "Vovida Open Communication Application Library", 00253 * and "Vovida Open Communication Application Library (VOCAL)" must 00254 * not be used to endorse or promote products derived from this 00255 * software without prior written permission. For written 00256 * permission, please contact vocal@vovida.org. 00257 * 00258 * 4. Products derived from this software may not be called "VOCAL", nor 00259 * may "VOCAL" appear in their name, without prior written 00260 * permission of Vovida Networks, Inc. 00261 * 00262 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED 00263 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00264 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND 00265 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA 00266 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES 00267 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, 00268 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00269 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00270 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 00271 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00272 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 00273 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 00274 * DAMAGE. 00275 * 00276 */
1.7.5.1