Timer.h
上传用户:sy_wanhua
上传日期:2013-07-25
资源大小:3048k
文件大小:8k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

C/C++

  1. #ifndef TIMER_H_
  2. #define TIMER_H_
  3. /* ====================================================================
  4.  * The Vovida Software License, Version 1.0 
  5.  * 
  6.  * Copyright (c) 2000 Vovida Networks, Inc.  All rights reserved.
  7.  * 
  8.  * Redistribution and use in source and binary forms, with or without
  9.  * modification, are permitted provided that the following conditions
  10.  * are met:
  11.  * 
  12.  * 1. Redistributions of source code must retain the above copyright
  13.  *    notice, this list of conditions and the following disclaimer.
  14.  * 
  15.  * 2. Redistributions in binary form must reproduce the above copyright
  16.  *    notice, this list of conditions and the following disclaimer in
  17.  *    the documentation and/or other materials provided with the
  18.  *    distribution.
  19.  * 
  20.  * 3. The names "VOCAL", "Vovida Open Communication Application Library",
  21.  *    and "Vovida Open Communication Application Library (VOCAL)" must
  22.  *    not be used to endorse or promote products derived from this
  23.  *    software without prior written permission. For written
  24.  *    permission, please contact vocal@vovida.org.
  25.  *
  26.  * 4. Products derived from this software may not be called "VOCAL", nor
  27.  *    may "VOCAL" appear in their name, without prior written
  28.  *    permission of Vovida Networks, Inc.
  29.  * 
  30.  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
  31.  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  32.  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
  33.  * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
  34.  * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
  35.  * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
  36.  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  37.  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  38.  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  39.  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  40.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
  41.  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  42.  * DAMAGE.
  43.  * 
  44.  * ====================================================================
  45.  * 
  46.  * This software consists of voluntary contributions made by Vovida
  47.  * Networks, Inc. and many individuals on behalf of Vovida Networks,
  48.  * Inc.  For more information on Vovida Networks, Inc., please see
  49.  * <http://www.vovida.org/>.
  50.  *
  51.  */
  52. static const char* const TimerHeaderVersion =
  53.     "$Id: Timer.h,v 1.23 2001/02/01 01:23:12 icahoon Exp $";
  54. #include "debug.h"
  55. #include "VMutex.h"
  56. #include "VTime.hxx"
  57. #include <unistd.h>
  58. #include "global.h"
  59. #include <list>
  60. bool operator < ( const timeval& lhs, const timeval& rhs);
  61. void addMs ( timeval* lhs, int timeMs);
  62. void subMs ( timeval* lhs, int timeMs);
  63. long tv_diff ( const timeval& lhs, const timeval& rhs);
  64. typedef unsigned int TimerEventId ;
  65. template < class X >
  66. class TimerObj
  67. {
  68.     public:
  69.         TimerObj()
  70.         {}
  71.         TimerObj(const TimerObj& x) :
  72.         myTime(x.myTime),
  73.         myObject(x.myObject),
  74.         eventId(x.eventId)
  75.         {}
  76.         TimerObj(const timeval& time, X object) :
  77.         myTime(time),
  78.         myObject(object),
  79.         eventId(0)
  80.         {}
  81.         // assignment operator
  82.         void operator = (const TimerObj& x)
  83.         {
  84.             myTime = x.myTime;
  85.             myObject = x.myObject;
  86.             eventId = x.eventId;
  87.         }
  88.         // equality check operator
  89.         bool operator == (const TimerObj& x)
  90.         {
  91.             if ((myTime.tv_sec == x.myTime.tv_sec) && (myTime.tv_usec == x.myTime.tv_usec) && (myObject == x.myObject) && (eventId == x.eventId))
  92.                 return ( true );
  93.             return ( false );
  94.         }
  95.         timeval myTime;
  96.         X myObject;
  97.         TimerEventId eventId;
  98. };
  99. template < class X > bool operator < (const TimerObj < X > & x, const TimerObj < X > & y)
  100. {
  101.     return x.myTime < y.myTime;
  102. }
  103. template < class T >
  104. class Timer
  105. {
  106.     public:
  107.         Timer();
  108.         Timer(long usecWait, T bad);
  109.         Timer(const timeval& minWait, T bad);
  110.         void insert(T obj, int msDelay);
  111.         void remove(const TimerObj < T > & obj);
  112.         TimerObj < T > getlastInserted()
  113.         {
  114.             return lastInserted;
  115.         }
  116.         bool sleepFor(timeval* t);
  117.         bool ready();
  118.         T top();
  119.         void pop();
  120.     private:
  121.         TimerEventId nextEventId;
  122.         list < TimerObj < T > > events;
  123.         //    priority_queue<TimerObj<T> > events;
  124.         VMutex* timerMutex;
  125.         timeval myMinWait;
  126.         T bogus;
  127.         static TimerObj < T > lastInserted;
  128. };
  129. template < class T > TimerObj < T > Timer < T > ::lastInserted = TimerObj < T > ();
  130. template < class T >
  131. Timer < T > ::Timer()
  132.         : nextEventId(0)
  133. {
  134.     timerMutex = new VMutex;
  135.     myMinWait.tv_sec = 0;
  136.     myMinWait.tv_usec = 0;
  137.     TimerObj < T > foo;
  138.     events.push_back(foo);
  139.     pop();
  140. }
  141. template < class T >
  142. Timer < T > ::Timer(long usecWait, T bad)
  143.         : nextEventId(0),
  144.         bogus(bad)
  145. {
  146.     timerMutex = new VMutex;
  147.     myMinWait.tv_sec = 0;
  148.     myMinWait.tv_usec = usecWait;
  149.     while(myMinWait.tv_usec > 1000000)
  150.     {
  151.         myMinWait.tv_sec++;
  152.         myMinWait.tv_usec -= 1000000;
  153.     }
  154.     TimerObj < T > foo;
  155.     events.push_back(foo);
  156.     pop();
  157. }
  158. template < class T >
  159. Timer < T > ::Timer(const timeval& minWait, T bad)
  160.         : nextEventId(0),
  161.         myMinWait(minWait),
  162.         bogus(bad)
  163. {
  164.     timerMutex = new VMutex;
  165.     TimerObj < T > foo;
  166.     events.push_back(foo);
  167.     pop();
  168. }
  169. template < class T >
  170. bool Timer < T > ::sleepFor(timeval* t)
  171. {
  172.     timeval now;
  173.     bool retval;
  174.     int err = gettimeofday(&now, NULL);
  175.     assert( !err );
  176.     timerMutex->lock();
  177.     if (!events.empty())
  178.     {
  179.         if (events.front().myTime < now)
  180.         {
  181.             // indicate almost no time to wait!
  182.             t->tv_sec = 0;
  183.             t->tv_usec = 1;
  184.             XDEBUG(3, cout << "diff: " << tv_diff(events.front().myTime, now) << endl; ) ;
  185.             retval = false;
  186.         }
  187.         else
  188.         {
  189.             t->tv_sec = events.front().myTime.tv_sec - now.tv_sec;
  190.             t->tv_usec = events.front().myTime.tv_usec - now.tv_usec;
  191.             while (t->tv_usec < 0)
  192.             {
  193.                 t->tv_sec--;
  194.                 t->tv_usec += 1000000;
  195.             }
  196.             retval = true;
  197.         }
  198.     }
  199.     else
  200.     {
  201.         *t = myMinWait;
  202.         retval = true;
  203.     }
  204.     timerMutex->unlock();
  205.     return retval;
  206. }
  207. template < class T >
  208. void Timer < T > ::insert(T obj, int msDelay)
  209. {
  210.     assert( INT_MAX > 2000000000 );
  211.     assert( INT_MIN < -2000000000 );
  212.     timeval now;
  213.     int err = gettimeofday(&now, NULL);
  214.     assert( !err );
  215.     XDEBUG(3, cout << "DELAY: " << msDelay << endl;
  216.           );
  217.     addMs(&now, msDelay);
  218.     TimerObj < T > x(now, obj);
  219.     // add the event to the priority queue
  220.     // lock the object
  221.     timerMutex->lock();
  222.     // get a new ID
  223.     TimerEventId id = nextEventId++;
  224.     x.eventId = id;
  225.     // put the message on the FIFO
  226.     events.push_back( x );
  227.     // save the last inserted item
  228.     lastInserted = x;
  229.     // get the list into priority order
  230.     events.sort();
  231.     // unlock the object
  232.     timerMutex->unlock();
  233. }
  234. template < class T >
  235. void Timer < T > ::remove(const TimerObj < T > & obj )
  236. {
  237.     if(!events.empty())
  238.     {
  239.         timerMutex->lock();
  240.         events.remove( obj );
  241.         timerMutex->unlock();
  242.     }
  243. }
  244. template < class T >
  245. void Timer < T > ::pop()
  246. {
  247.     if(!events.empty())
  248.     {
  249.         timerMutex->lock();
  250.         events.pop_front();
  251.         timerMutex->unlock();
  252.     }
  253. }
  254. template < class T >
  255. bool Timer < T > ::ready()
  256. {
  257.     timeval now;
  258.     int err = gettimeofday(&now, NULL);
  259.     assert( !err );
  260.     if (!events.empty())
  261.     {
  262.         if (events.front().myTime < now)
  263.         {
  264.             return true;
  265.         }
  266.     }
  267.     return false;
  268. }
  269. template < class T >
  270. T Timer < T > ::top()
  271. {
  272.     if(!events.empty())
  273.     {
  274.         return events.front().myObject;
  275.     }
  276.     return bogus;
  277. }
  278. #endif