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

流媒体/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. static const char* const ServiceManager_cxx_Version = 
  51.     "$Id: ServiceManager.cxx,v 1.6 2001/06/27 23:12:00 bko Exp $";
  52. #include "ServiceManager.hxx"
  53. #include "Service.hxx"
  54. #include "ControlEvent.hxx"
  55. #include "SignalAction.hxx"
  56. #include "SignalHandler.hxx"
  57. #include "Thread.hxx"
  58. #include "VLog.hxx"
  59. using Vocal::Services::Event;
  60. using Vocal::Services::ServiceManager;
  61. using Vocal::Services::ControlEvent;
  62. using Vocal::Signals::SignalAction;
  63. using Vocal::Threads::Thread;
  64. using Vocal::Logging::VLog;
  65. using Vocal::ReturnCode;
  66. ServiceManager::ServiceManager(
  67.     FifoBase< Sptr<Event> >  &   serviceMgrFifo,
  68.     SignalAction                *   signalAction
  69. )
  70.     : myFifo(serviceMgrFifo),
  71.         mySignalAction(signalAction)
  72. {
  73.     const string    fn("ServiceManager::ServiceMananger");
  74.     VLog         log(fn);
  75.     
  76.     VDEBUG(log) << fn << ": this = 0x" << this << VDEBUG_END(log);
  77. }
  78. ServiceManager::~ServiceManager()
  79. {
  80.     const string    fn("ServiceManager::~ServiceMananger");
  81.     VLog         log(fn);
  82.     
  83.     VDEBUG(log) << fn << ": this = 0x" << this << VDEBUG_END(log);
  84. }
  85. void
  86. ServiceManager::manage(Service & service)
  87. {
  88.     const string    fn("ServiceManager::manage");
  89.     VLog         log(fn);
  90.     
  91.     VINFO(log) << fn << ": service = " << service.name() << VINFO_END(log);
  92.     ServiceInfo serviceInfo;
  93.     
  94.     serviceInfo.service = &service;
  95.     serviceInfo.thread = new Thread(service, service.name().c_str());
  96.     
  97.     myServiceList.push_back(serviceInfo);
  98. }
  99. void
  100. ServiceManager::unmanage()
  101. {
  102.     const string    fn("ServiceManager::unmanage");
  103.     VLog         log(fn);
  104.     
  105.     for (   ServiceList::reverse_iterator i = myServiceList.rbegin();
  106.             i != myServiceList.rend();
  107.             ++i
  108.         )
  109.     {
  110.         VINFO(log) << fn << ": service = " << i->service->name() 
  111.                    << VINFO_END(log);
  112.                    
  113.         i->thread->join();
  114.         delete i->thread;
  115.         i->thread = 0;
  116.     }
  117.     
  118.     myServiceList.clear();
  119. }
  120. ReturnCode
  121. ServiceManager::start()
  122. {
  123.     const string    fn("ServiceManager::start");
  124.     VLog         log(fn);
  125.     ReturnCode rc = SUCCESS;
  126.         
  127.     for (   ServiceList::iterator iter = myServiceList.begin();
  128.          rc == SUCCESS && iter != myServiceList.end();
  129.     ++iter
  130. )
  131.     {
  132.      Service &   service = *(iter->service);
  133. Sptr<ControlEvent> startEvent 
  134.          = new ControlEvent(ControlEvent::START, myFifo);
  135.     
  136.      int     startId = startEvent->getControlEventId();
  137.     
  138.      service.getFifo().add(startEvent);
  139.     
  140. bool    started = false;
  141.      while ( !started )
  142.      {
  143.     bool done = block();
  144.     
  145.     if ( done == true )
  146.     {
  147.                 VINFO(log) << fn << ": Exiting on signal." << VINFO_END(log);
  148.      break;
  149.     }
  150.         
  151.             Sptr<Event> event;
  152.     
  153.             while ( !started && myFifo.messageAvailable() )
  154.             {
  155.              event = myFifo.getNext();
  156.           Sptr<ControlEvent> ctrlEvent;
  157.           ctrlEvent.dynamicCast(event);
  158.      if ( ctrlEvent == 0 )
  159. {
  160.     VWARN(log)  << fn << ": Unknown event: " 
  161.           << ( event == 0 ? "No event" : event->name() )
  162.      << VWARN_END(log);
  163.          continue;
  164. }
  165.      if ( ctrlEvent->getType() == ControlEvent::START )
  166. {
  167.               if ( ctrlEvent->getControlEventId() == startId )
  168.     {
  169. started = true;
  170.                rc = ctrlEvent->getReturnCode();
  171.           if ( rc != SUCCESS )
  172. {
  173.     VWARN(log)  << fn << ": Service: " << service.name()
  174.                                         << ", start returned error. shutting down."
  175.           << VWARN_END(log);
  176. }
  177.           VINFO(log) << fn << ": Service: " << service.name()
  178.                                    << ", started, rc = " << rc
  179.              << VINFO_END(log);
  180.     }
  181.     else
  182.     {
  183. VWARN(log)  << fn << ": Unknown control event: " 
  184.          << *ctrlEvent << VWARN_END(log);
  185.     }
  186. }
  187. else
  188. {
  189.     VWARN(log)  << fn << ": Unknown control event: " 
  190.      << *ctrlEvent << VWARN_END(log);
  191. }
  192.     }
  193. }
  194.     }
  195.     return ( rc );
  196. }
  197. ReturnCode
  198. ServiceManager::run()
  199. {
  200.     const string    fn("ServiceManager::run");
  201.     VLog         log(fn);
  202.     ReturnCode rc       = SUCCESS;
  203.     bool     shutdown    = false;
  204.     
  205.     while ( rc == SUCCESS )
  206.     {
  207.      bool done = block(); 
  208. if ( done == true )
  209. {
  210.             VINFO(log) << fn << ": exiting on signal." << VINFO_END(log);
  211.     break;
  212. }
  213.      Sptr<Event> event;
  214.      while ( !shutdown && myFifo.messageAvailable() )
  215.      {
  216.          event = myFifo.getNext();
  217.          Sptr<ControlEvent> ctrlEvent;
  218.          ctrlEvent.dynamicCast(event);
  219.          if ( ctrlEvent == 0 )
  220.     {
  221. VWARN(log)  << fn << ": Unknown event: " 
  222.               << ( event == 0 ? "No event" : event->name() )
  223.          << VWARN_END(log);
  224.          }
  225.     
  226.          switch ( ctrlEvent->getType() )
  227.          {
  228.      // We received an unsolicited stop or shutdown message.
  229. // It's trouble, so let's shutdown.
  230. //
  231. case ControlEvent::STOP:
  232. case ControlEvent::SHUTDOWN:
  233. {
  234.     rc = !SUCCESS;
  235.     shutdown = true;
  236.               VWARN(log) << fn << ": terminate via failure." 
  237.             << VWARN_END(log);
  238.     break;
  239. }
  240. default:
  241.      {
  242.     break;
  243. }
  244.     }
  245. }
  246.     }
  247.     
  248.     return ( rc );
  249. }
  250. void
  251. ServiceManager::stop()
  252. {
  253.     const string    fn("ServiceManager::stop");
  254.     VLog         log(fn);
  255.     for (   ServiceList::reverse_iterator iter = myServiceList.rbegin();
  256.          iter != myServiceList.rend();
  257.     ++iter
  258. )
  259.     {
  260.      Service &   service = *(iter->service);
  261. Sptr<ControlEvent> stopEvent 
  262.     = new ControlEvent(ControlEvent::STOP, myFifo);
  263. int stopId = stopEvent->getControlEventId();
  264. service.getFifo().add(stopEvent);
  265. bool stopped = false;
  266. while ( !stopped )
  267. {
  268.     block();
  269.             Sptr<Event> event;
  270.             while ( !stopped && myFifo.messageAvailable() )
  271.             {
  272.          event = myFifo.getNext();
  273.      Sptr<ControlEvent> ctrlEvent;
  274.      ctrlEvent.dynamicCast(event);
  275.      if ( ctrlEvent == 0 )
  276. {
  277.     VWARN(log)  << fn << ": Unknown event: " 
  278.           << ( event == 0 ? "No event" : event->name() )
  279.      << VWARN_END(log);
  280.     continue;
  281. }
  282.      if  (   ctrlEvent->getType() == ControlEvent::STOP
  283.     &&  ctrlEvent->getControlEventId() == stopId
  284.     )
  285. {
  286.     stopped = true;
  287.               VINFO(log) << fn << ": Serivce: " << service.name()
  288.                                << ", stopped." << VINFO_END(log);
  289. }
  290. else
  291. {
  292.     VWARN(log)  << fn << ": Unknown service control event: " 
  293.      << *ctrlEvent << VWARN_END(log);
  294. }
  295.     }
  296. }
  297.     }
  298. }
  299. void
  300. ServiceManager::shutdown()
  301. {
  302.     const string    fn("ServiceManager::shutdown");
  303.     VLog         log(fn);
  304.     for (   ServiceList::reverse_iterator iter = myServiceList.rbegin();
  305.          iter != myServiceList.rend();
  306.     ++iter
  307. )
  308.     {
  309.      Service &   service = *(iter->service);
  310. Sptr<ControlEvent> shutdownEvent;
  311. shutdownEvent = new ControlEvent(ControlEvent::SHUTDOWN, myFifo);
  312. service.getFifo().add(shutdownEvent);
  313. VINFO(log) << fn << ": shutdown sent." << VINFO_END(log);
  314.     }
  315. }
  316. void     
  317. ServiceManager::blockSignals()
  318. {
  319.     if ( mySignalAction )
  320.     {
  321.         Thread::self()->signalHandler().block(mySignalAction->signalSet());
  322.     }
  323. }
  324. void     
  325. ServiceManager::unblockSignals()
  326. {
  327.     if ( mySignalAction )
  328.     {
  329.         Thread::self()->signalHandler().unblock(mySignalAction->signalSet());
  330.     }
  331. }
  332. bool
  333. ServiceManager::signalCaught()
  334. {
  335.     if ( mySignalAction )
  336.     {
  337.         return ( mySignalAction->signalCaught() );
  338.     }
  339.     return ( false );
  340. }
  341. bool
  342. ServiceManager::block()
  343. {
  344.     const string    fn("ServiceManager::block");
  345.     VLog         log(fn);
  346.     
  347.     unblockSignals();
  348.     myFifo.block();
  349.     blockSignals();
  350.     VVERBOSE(log) << fn << ": fifo block returned." << VVERBOSE_END(log);
  351.     return ( signalCaught() );
  352. }