FifoBase-win32.cxx
上传用户:sy_wanhua
上传日期:2013-07-25
资源大小:3048k
文件大小:9k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

C/C++

  1. /* ====================================================================
  2.  * The Vovida Software License, Version 1.0 
  3.  * 
  4.  * Copyright (c) 2000 Vovida Networks, Inc.  All rights reserved.
  5.  * 
  6.  * Redistribution and use in source and binary forms, with or without
  7.  * modification, are permitted provided that the following conditions
  8.  * are met:
  9.  * 
  10.  * 1. Redistributions of source code must retain the above copyright
  11.  *    notice, this list of conditions and the following disclaimer.
  12.  * 
  13.  * 2. Redistributions in binary form must reproduce the above copyright
  14.  *    notice, this list of conditions and the following disclaimer in
  15.  *    the documentation and/or other materials provided with the
  16.  *    distribution.
  17.  * 
  18.  * 3. The names "VOCAL", "Vovida Open Communication Application Library",
  19.  *    and "Vovida Open Communication Application Library (VOCAL)" must
  20.  *    not be used to endorse or promote products derived from this
  21.  *    software without prior written permission. For written
  22.  *    permission, please contact vocal@vovida.org.
  23.  *
  24.  * 4. Products derived from this software may not be called "VOCAL", nor
  25.  *    may "VOCAL" appear in their name, without prior written
  26.  *    permission of Vovida Networks, Inc.
  27.  * 
  28.  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
  29.  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  30.  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
  31.  * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
  32.  * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
  33.  * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
  34.  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  35.  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  36.  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  37.  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  38.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
  39.  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  40.  * DAMAGE.
  41.  * 
  42.  * ====================================================================
  43.  * 
  44.  * This software consists of voluntary contributions made by Vovida
  45.  * Networks, Inc. and many individuals on behalf of Vovida Networks,
  46.  * Inc.  For more information on Vovida Networks, Inc., please see
  47.  * <http://www.vovida.org/>.
  48.  *
  49.  */
  50. #ifdef WIN32
  51. static const char* const FifoBase_win32_cxx_Version =
  52.     "$Id: FifoBase-win32.cxx,v 1.2 2001/06/29 20:45:34 bko Exp $";
  53. #include "Lock.hxx"
  54. //#include "FifoBase.h"
  55. using namespace Vocal;
  56. using namespace Vocal::TimeAndDate;
  57. using Process::Lock;
  58. template < class Msg >
  59. FifoBase < Msg > ::FifoBase()
  60.         : shutdown_(false)
  61. {}
  62. template < class Msg >
  63. FifoBase < Msg > ::~FifoBase()
  64. {}
  65. template < class Msg >
  66. void
  67. FifoBase < Msg > ::add(const Msg & msg)
  68. {
  69.     Lock lock(mutex_);
  70.     (void)lock;
  71.     if ( shutdown_ )
  72.     {
  73.         return ;
  74.     }
  75.     fifo_.push_back(new Msg(msg));
  76.     try
  77.     {
  78.         wakeup();
  79.     }
  80.     catch ( VException & )
  81.     {
  82.         assert(0);
  83.     }
  84. }
  85. template < class Msg >
  86. FifoBase < Msg > ::EventId
  87. FifoBase < Msg > ::addDelayMs(
  88.     const Msg & msg,
  89.     const milliseconds_t relativeTimeout__
  90. )
  91. {
  92.     Lock lock(mutex_);
  93.     (void)lock;
  94.     if ( shutdown_ )
  95.     {
  96.         return ( 0 );
  97.     }
  98.     milliseconds_t relativeTimeout = relativeTimeout__;
  99.     if ( relativeTimeout < 0 )
  100.     {
  101.         relativeTimeout = 0;
  102.     }
  103.     TimerEntryId newId = timer_.add(new Msg(msg), relativeTimeout);
  104.     TimerEntryId firstId = timer_.getFirstTimerEntryId();
  105.     // If we insert the new message at the front of the timer list,
  106.     // we need to wakeup wait() since we have a timed message that
  107.     // expires sooner than the current, or if we didn't have a timer
  108.     // to begin with.
  109.     //
  110.     if ( firstId == newId )
  111.     {
  112.         try
  113.         {
  114.             wakeup();
  115.         }
  116.         catch ( VException & )
  117.         {
  118.             assert(0);
  119.         }
  120.     }
  121.     return ( newId );
  122. }
  123. template < class Msg >
  124. void
  125. FifoBase < Msg > ::cancel(EventId id)
  126. {
  127.     if ( id == 0 )
  128.     {
  129.         return ;
  130.     }
  131.     Lock lock(mutex_);
  132.     (void)lock;
  133.     if ( !timer_.cancel(id) )
  134.     {
  135.         // If the timer didn't hold the message to cancel, walk through
  136.         // the queue and see if we have it there.
  137.         //
  138.         for ( MessageContainer::iterator it = fifo_.begin();
  139.                 it != fifo_.end();
  140.                 it++
  141.             )
  142.         {
  143.             // Assertion: The id for a timed event is just the
  144.             // address of the memory for the message. If this isn't
  145.             // true in TimerEntry, then we have problems.
  146.             //
  147.             if ( id == (EventId)((*it).operator->()) )
  148.             {
  149.                 fifo_.erase(it);
  150.                 return ;
  151.             }
  152.         }
  153.     }
  154. }
  155. template < class Msg >
  156. int
  157. FifoBase < Msg > ::block(milliseconds_t relativeTimeout)
  158. throw ( VException )
  159. {
  160.     Lock lock(mutex_);
  161.     (void)lock;
  162.     if ( messageAvailableNoLock() )
  163.     {
  164.         return ( 1 );
  165.     }
  166.     return ( blockNoLock(relativeTimeout) );
  167. }
  168. template < class Msg >
  169. Msg
  170. FifoBase < Msg > ::getNext()
  171. throw ( VException )
  172. {
  173.     Lock lock(mutex_);
  174.     (void)lock;
  175.     // Wait while there are no messages available.
  176.     //
  177.     while ( !messageAvailableNoLock() )
  178.     {
  179.         blockNoLock();
  180.     }
  181.     // Move expired timers into fifo.
  182.     //
  183.     while ( timer_.messageAvailable() )
  184.     {
  185.         try
  186.         {
  187.             fifo_.push_back(timer_.getMessage());
  188.         }
  189.         catch ( ... )
  190.         {
  191.             assert(0);
  192.         }
  193.     }
  194.     // Return the first message on the fifo.
  195.     //
  196.     Msg firstMessage = *(fifo_.front());
  197.     fifo_.pop_front();
  198.     return ( firstMessage );
  199. }
  200. template < class Msg >
  201. unsigned int
  202. FifoBase < Msg > ::size() const
  203. {
  204.     Lock lock(mutex_);
  205.     (void)lock;
  206.     return ( fifo_.size() + timer_.size() );
  207. }
  208. template < class Msg >
  209. bool
  210. FifoBase < Msg > ::messageAvailable()
  211. {
  212.     Lock lock(mutex_);
  213.     (void)lock;
  214.     return ( messageAvailableNoLock() );
  215. }
  216. template < class Msg >
  217. void
  218. FifoBase < Msg > ::shutdown()
  219. {
  220.     Lock lock(mutex_);
  221.     (void)lock;
  222.     shutdown_ = true;
  223. }
  224. template < class Msg >
  225. bool
  226. FifoBase < Msg > ::operator==(const FifoBase & src) const
  227. {
  228.     // Since each oberver is unique, we can compare addresses.
  229.     //
  230.     return ( this == &src );
  231. }
  232. template < class Msg >
  233. bool
  234. FifoBase < Msg > ::operator!=(const FifoBase & src) const
  235. {
  236.     return ( this != &src );
  237. }
  238. template < class Msg >
  239. bool
  240. FifoBase < Msg > ::operator<(const FifoBase & src) const
  241. {
  242.     return ( this < &src );
  243. }
  244. template < class Msg >
  245. bool
  246. FifoBase < Msg > ::operator<=(const FifoBase & src) const
  247. {
  248.     return ( this <= &src );
  249. }
  250. template < class Msg >
  251. bool
  252. FifoBase < Msg > ::operator>(const FifoBase & src) const
  253. {
  254.     return ( this > &src );
  255. }
  256. template < class Msg >
  257. bool
  258. FifoBase < Msg > ::operator>=(const FifoBase & src) const
  259. {
  260.     return ( this >= &src );
  261. }
  262. template < class Msg >
  263. bool
  264. FifoBase < Msg > ::messageAvailableNoLock()
  265. {
  266.     return ( fifo_.size() > 0 || timer_.messageAvailable() );
  267. }
  268. template < class Msg >
  269. int
  270. FifoBase < Msg > ::blockNoLock(milliseconds_t relativeTimeout)
  271. throw ( VException )
  272. {
  273.     // Use the shortest timeout value between the given relativeTimout
  274.     // and the timer container's timeout, remembering that infinite timeout
  275.     // is specified by a negative number.
  276.     //
  277.     milliseconds_t timerTimeout = timer_.getTimeout(),
  278.                                   timeout;
  279.     // If timerTimeout is infinite, relativeTimeout can only be the
  280.     // same or shorter.
  281.     //
  282.     if ( timerTimeout < 0 )
  283.     {
  284.         timeout = relativeTimeout;
  285.     }
  286.     // If relativeTimeout is infinite, timerTimeout can only be the
  287.     // same or shorter.
  288.     //
  289.     else if ( relativeTimeout < 0 )
  290.     {
  291.         timeout = timerTimeout;
  292.     }
  293.     // Both are positive timeout values. Take the shortest in duration.
  294.     else
  295.     {
  296.         timeout = relativeTimeout < timerTimeout
  297.                   ? relativeTimeout
  298.                   : timerTimeout;
  299.     }
  300.     // Wait for an event. A timer expiry or signal will return a 0 here.
  301.     //
  302.     int numberActive = wait(timeout);
  303.     if ( numberActive > 0 )
  304.     {
  305.         return ( numberActive );
  306.     }
  307.     // See if a timer has expired.  If it has expired, return 1 to indicate
  308.     // a message is available from the timer.
  309.     //
  310.     if ( messageAvailableNoLock() )
  311.     {
  312.         return ( 1 );
  313.     }
  314.     // To get here, either a signal woke us up, or the we used the
  315.     // relativeTimeout value, meaning that a message isn't available from
  316.     // the timer container.
  317.     //
  318.     return ( 0 );
  319. }
  320. #endif // WIN32