|
reSIProcate/stack
9694
|
00001 #ifndef resip_CancelableTimerQueue_hxx 00002 #define resip_CancelableTimerQueue_hxx 00003 00004 #include <map> 00005 #include <limits.h> 00006 #include <iosfwd> 00007 00008 #include "rutil/Timer.hxx" 00009 #include "rutil/HashMap.hxx" 00010 #include "rutil/Inserter.hxx" 00011 00012 using namespace std; 00013 00014 namespace resip 00015 { 00016 00017 template<class T> 00018 class CancelableTimerQueue 00019 { 00020 public: 00021 CancelableTimerQueue() : mNextId(0) {}; 00022 ~CancelableTimerQueue() {}; 00023 00024 typedef long Id; 00025 private: 00026 typedef std::multimap< UInt64, std::pair<T, Id> > TimerMap; 00027 typedef HashMap<Id, UInt64> IdToTimer; 00028 00029 public: 00030 Id addRelative(T msg, 00031 unsigned int offset) 00032 { 00033 return addTimer(msg, resip::Timer::getTimeMs() + offset); 00034 } 00035 00036 //returns true if the id existed 00037 bool cancel(Id id) 00038 { 00039 typename IdToTimer::iterator j = mIdToTimer.find(id); 00040 if (j == mIdToTimer.end()) 00041 { 00042 return false; 00043 } 00044 00045 for (typename TimerMap::iterator i = mTimerMap.lower_bound(j->second); i != mTimerMap.upper_bound(j->second); i++) 00046 { 00047 if (i->second.second == id) 00048 { 00049 mTimerMap.erase(i); 00050 mIdToTimer.erase(j); 00051 return true; 00052 } 00053 } 00054 //cerr << "mIdToTimer: " << Inserter(mIdToTimer) << endl; 00055 //cerr << "Searching for ID: " << id << endl; 00056 //cerr << "TimerMap state: " << Inserter(mTimerMap) << endl; 00057 assert(mIdToTimer.size() == mTimerMap.size()); 00058 assert(0); 00059 } 00060 00061 //get the number of milliseconds until the next event, returns -1 if no 00062 //event is available 00063 int getTimeout() const 00064 { 00065 if (mTimerMap.empty()) 00066 { 00067 return -1; 00068 } 00069 else 00070 { 00071 if (mTimerMap.begin()->first - resip::Timer::getTimeMs() < 0) 00072 { 00073 return 0; 00074 } 00075 else 00076 { 00077 return mTimerMap.begin()->first - resip::Timer::getTimeMs(); 00078 } 00079 } 00080 } 00081 00082 bool available() const 00083 { 00084 return (!mTimerMap.empty() && 00085 mTimerMap.begin()->first <= resip::Timer::getTimeMs()); 00086 } 00087 00088 T getNext() 00089 { 00090 assert(mIdToTimer.size() == mTimerMap.size()); 00091 00092 assert(available()); 00093 00094 typename TimerMap::iterator it = mTimerMap.begin(); 00095 mIdToTimer.erase(it->second.second); 00096 00097 T msg = it->second.first; 00098 mTimerMap.erase(it); 00099 00100 assert(mIdToTimer.size() == mTimerMap.size()); 00101 00102 return msg; 00103 } 00104 00105 void clear() 00106 { 00107 mTimerMap.clear(); 00108 mIdToTimer.clear(); 00109 } 00110 00111 bool empty() const 00112 { 00113 return mTimerMap.empty(); 00114 } 00115 00116 size_t size() const 00117 { 00118 return mTimerMap.size(); 00119 } 00120 00121 private: 00122 00123 Id addTimer(T msg, UInt64 expiry) 00124 { 00125 Id id = getNextId(); 00126 mTimerMap.insert(std::make_pair(expiry, std::make_pair(msg, id))); 00127 mIdToTimer[id] = expiry; 00128 assert(mIdToTimer.size() == mTimerMap.size()); 00129 return id; 00130 } 00131 00132 Id getNextId() 00133 { 00134 mNextId++; 00135 if (mNextId == INT_MAX) 00136 { 00137 mNextId = 1; 00138 } 00139 return mNextId; 00140 } 00141 00142 Id mNextId; 00143 IdToTimer mIdToTimer; 00144 TimerMap mTimerMap; 00145 }; 00146 00147 } 00148 00149 #endif 00150 /* ==================================================================== 00151 * The Vovida Software License, Version 1.0 00152 * 00153 * Copyright (c) 2004 PurpleComm, Inc. All rights reserved. 00154 * 00155 * Redistribution and use in source and binary forms, with or without 00156 * modification, are permitted provided that the following conditions 00157 * are met: 00158 * 00159 * 1. Redistributions of source code must retain the above copyright 00160 * notice, this list of conditions and the following disclaimer. 00161 * 00162 * 2. Redistributions in binary form must reproduce the above copyright 00163 * notice, this list of conditions and the following disclaimer in 00164 * the documentation and/or other materials provided with the 00165 * distribution. 00166 * 00167 * 3. The names "VOCAL", "Vovida Open Communication Application Library", 00168 * and "Vovida Open Communication Application Library (VOCAL)" must 00169 * not be used to endorse or promote products derived from this 00170 * software without prior written permission. For written 00171 * permission, please contact vocal@vovida.org. 00172 * 00173 * 4. Products derived from this software may not be called "VOCAL", nor 00174 * may "VOCAL" appear in their name, without prior written 00175 * permission of Vovida Networks, Inc. 00176 * 00177 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED 00178 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00179 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND 00180 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA 00181 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES 00182 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, 00183 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00184 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00185 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 00186 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00187 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 00188 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 00189 * DAMAGE. 00190 * 00191 */
1.7.5.1