reSIProcate/stack  9694
TimerQueue.hxx
Go to the documentation of this file.
00001 #if !defined(RESIP_TIMERQUEUE_HXX)
00002 #define RESIP_TIMERQUEUE_HXX 
00003 
00004 #if defined(HAVE_CONFIG_H)
00005   #include "config.h"
00006 #endif
00007 
00008 #include <queue>
00009 #include <set>
00010 #include <iosfwd>
00011 #include "resip/stack/TimerMessage.hxx"
00012 #include "resip/stack/DtlsMessage.hxx"
00013 #include "rutil/Fifo.hxx"
00014 #include "rutil/TimeLimitFifo.hxx"
00015 #include "rutil/Timer.hxx"
00016 
00017 // .dlb. 
00018 // to do: timer wheel for transaction-bound timers and a heap for
00019 // everything longer.
00020 
00021 namespace resip
00022 {
00023 
00024 class Message;
00025 class TransactionMessage;
00026 class TuSelector;
00027 
00038 template <class T>
00039 class TimerQueue
00040 {
00041    public:
00042       // This is the logic that runs when a timer goes off. This is the only
00043       // thing subclasses must implement.
00044       virtual void processTimer(const T& timer)=0;
00045 
00046 
00047 
00049       virtual ~TimerQueue()
00050       {
00051          //xkd-2004-11-4
00052          // delete the message associated with the timer
00053          while (!mTimers.empty())
00054          {
00055             mTimers.pop();
00056          }
00057       }
00058 
00064       unsigned int msTillNextTimer()
00065       {
00066          if (!mTimers.empty())
00067          {
00068             UInt64 next = mTimers.top().getWhen();
00069             UInt64 now = Timer::getTimeMs();
00070             if (now > next) 
00071             {
00072                return 0;
00073             }
00074             else
00075             {
00076                UInt64 ret64 = next - now;
00077                if ( ret64 > UInt64(INT_MAX) )
00078                {
00079                   return INT_MAX;
00080                }
00081                else
00082                { 
00083                   int ret = int(ret64);
00084                   return ret;
00085                }
00086             }
00087          }
00088          else
00089          {
00090             return INT_MAX;
00091          }
00092       }
00093 
00096       virtual UInt64 process()
00097       {
00098          if (!mTimers.empty())
00099          {
00100             UInt64 now=Timer::getTimeMs();
00101             while (!mTimers.empty() && !(mTimers.top().getWhen() > now))
00102             {
00103                processTimer(mTimers.top());
00104                mTimers.pop();
00105             }
00106 
00107             if(!mTimers.empty())
00108             {
00109                return mTimers.top().getWhen();
00110             }
00111          }
00112          return 0;
00113       }
00114 
00115       int size() const
00116       {
00117          return (int)mTimers.size();
00118       }
00119       bool empty() const
00120       {
00121          return mTimers.empty();
00122       }
00123 
00124 
00125       std::ostream& encode(std::ostream& str) const
00126       {
00127          if(mTimers.size() > 0)
00128          {
00129             return str << "TimerQueue[ size =" << mTimers.size() 
00130                        << " top=" << mTimers.top() << "]" ;
00131          }
00132          else
00133          {
00134             return str << "TimerQueue[ size = 0 ]";
00135          }
00136       }
00137 
00138 #ifndef RESIP_USE_STL_STREAMS
00139       EncodeStream& encode(EncodeStream& str) const
00140       {
00141          if(mTimers.size() > 0)
00142          {
00143             return str << "TimerQueue[ size =" << mTimers.size() 
00144                        << " top=" << mTimers.top() << "]" ;
00145          }
00146          else
00147          {
00148             return str << "TimerQueue[ size = 0 ]";
00149          }
00150       }
00151 #endif
00152 
00153    protected:
00154       typedef std::vector<T, std::allocator<T> > TimerVector;
00155       std::priority_queue<T, TimerVector, std::greater<T> > mTimers;
00156 };
00157 
00161 class BaseTimeLimitTimerQueue : public TimerQueue<TimerWithPayload>
00162 {
00163    public:
00164       UInt64 add(unsigned int timeMs,Message* payload);
00165       virtual void processTimer(const TimerWithPayload& timer);
00166    protected:
00167       virtual void addToFifo(Message*, TimeLimitFifo<Message>::DepthUsage)=0;      
00168 };
00169 
00170 
00174 class TimeLimitTimerQueue : public BaseTimeLimitTimerQueue
00175 {
00176    public:
00177       TimeLimitTimerQueue(TimeLimitFifo<Message>& fifo);
00178    protected:
00179       virtual void addToFifo(Message*, TimeLimitFifo<Message>::DepthUsage);
00180    private:
00181       TimeLimitFifo<Message>& mFifo;
00182 };
00183 
00184 
00188 class TuSelectorTimerQueue : public TimerQueue<TimerWithPayload>
00189 {
00190    public:
00191       TuSelectorTimerQueue(TuSelector& sel);
00192       UInt64 add(unsigned int timeMs,Message* payload);
00193       virtual void processTimer(const TimerWithPayload& timer);
00194    private:
00195       TuSelector& mFifoSelector;
00196 };
00197 
00198 
00202 class TransactionTimerQueue : public TimerQueue<TransactionTimer>
00203 {
00204    public:
00205       TransactionTimerQueue(Fifo<TimerMessage>& fifo);
00206       UInt64 add(Timer::Type type, const Data& transactionId, unsigned long msOffset);
00207       virtual void processTimer(const TransactionTimer& timer);
00208    private:
00209       Fifo<TimerMessage>& mFifo;
00210 };
00211 
00212 #ifdef USE_DTLS
00213 
00214 #include <openssl/ssl.h>
00215 
00219 class DtlsTimerQueue : public TimerQueue<TimerWithPayload>
00220 {
00221    public:
00222       DtlsTimerQueue( Fifo<DtlsMessage>& fifo ) ;
00223       UInt64 add( SSL *, unsigned long msOffset ) ;
00224       virtual void processTimer(const TimerWithPayload& timer) ;
00225       
00226    private:
00227       Fifo<DtlsMessage>& mFifo ;
00228 };
00229 
00230 #endif
00231 
00232 template <class T>
00233 std::ostream& operator<<(std::ostream& str, const TimerQueue<T>& tq)
00234 {
00235    return tq.encode(str);
00236 }
00237 
00238 #ifndef RESIP_USE_STL_STREAMS
00239 template <class T>
00240 EncodeStream& operator<<(EncodeStream& str, const TimerQueue<T>& tq)
00241 {
00242    return tq.encode(str);
00243 }
00244 #endif
00245 
00246 
00247 }
00248 
00249 #endif
00250 
00251 /* ====================================================================
00252  * The Vovida Software License, Version 1.0 
00253  * 
00254  * Copyright (c) 2004 Vovida Networks, Inc.  All rights reserved.
00255  * 
00256  * Redistribution and use in source and binary forms, with or without
00257  * modification, are permitted provided that the following conditions
00258  * are met:
00259  * 
00260  * 1. Redistributions of source code must retain the above copyright
00261  *    notice, this list of conditions and the following disclaimer.
00262  * 
00263  * 2. Redistributions in binary form must reproduce the above copyright
00264  *    notice, this list of conditions and the following disclaimer in
00265  *    the documentation and/or other materials provided with the
00266  *    distribution.
00267  * 
00268  * 3. The names "VOCAL", "Vovida Open Communication Application Library",
00269  *    and "Vovida Open Communication Application Library (VOCAL)" must
00270  *    not be used to endorse or promote products derived from this
00271  *    software without prior written permission. For written
00272  *    permission, please contact vocal@vovida.org.
00273  *
00274  * 4. Products derived from this software may not be called "VOCAL", nor
00275  *    may "VOCAL" appear in their name, without prior written
00276  *    permission of Vovida Networks, Inc.
00277  * 
00278  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
00279  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00280  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
00281  * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
00282  * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
00283  * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
00284  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00285  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00286  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
00287  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00288  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
00289  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
00290  * DAMAGE.
00291  * 
00292  * ====================================================================
00293  * 
00294  * This software consists of voluntary contributions made by Vovida
00295  * Networks, Inc. and many individuals on behalf of Vovida Networks,
00296  * Inc.  For more information on Vovida Networks, Inc., please see
00297  * <http://www.vovida.org/>.
00298  *
00299  */