⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 service.cxx

📁 Vovida 社区开源的 SIP 协议源码
💻 CXX
字号:
/* ==================================================================== * The Vovida Software License, Version 1.0  *  * Copyright (c) 2000 Vovida Networks, Inc.  All rights reserved. *  * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: *  * 1. Redistributions of source code must retain the above copyright *    notice, this list of conditions and the following disclaimer. *  * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in *    the documentation and/or other materials provided with the *    distribution. *  * 3. The names "VOCAL", "Vovida Open Communication Application Library", *    and "Vovida Open Communication Application Library (VOCAL)" must *    not be used to endorse or promote products derived from this *    software without prior written permission. For written *    permission, please contact vocal@vovida.org. * * 4. Products derived from this software may not be called "VOCAL", nor *    may "VOCAL" appear in their name, without prior written *    permission of Vovida Networks, Inc. *  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH * DAMAGE. *  * ==================================================================== *  * This software consists of voluntary contributions made by Vovida * Networks, Inc. and many individuals on behalf of Vovida Networks, * Inc.  For more information on Vovida Networks, Inc., please see * <http://www.vovida.org/>. * */static const char* const Service_cxx_Version =     "$Id: Service.cxx,v 1.11 2001/10/26 21:47:52 icahoon Exp $";#include "global.h"#include "Service.hxx"#include "VException.hxx"#include "SignalAction.hxx"#include "SignalHandler.hxx"#include "Thread.hxx"#include "VLog.hxx"#include <cassert>using namespace Vocal;using Vocal::Services::Service;using Vocal::Services::Event;using Vocal::Services::ControlEvent;using Vocal::Behavioral::EventObserver;using Vocal::Behavioral::EventSubject;using Vocal::Signals::SignalAction;using Vocal::Threads::Thread;using Vocal::Logging::VLog;Service::Service(    const char      	    	*   name)    :	myServiceManagerFifo(0),    	myName(name ? name : "Service"),        mySignalAction(0){}Service::~Service(){}FifoBase< Sptr<Event> > &   Service::getServiceManagerFifo(){    return ( myServiceManagerFifo ? *myServiceManagerFifo : getFifo() );}		const FifoBase< Sptr<Event> > &   Service::getServiceManagerFifo() const{    return ( myServiceManagerFifo ? *myServiceManagerFifo : getFifo() );}		voidService::setServiceManagerFifo(FifoBase< Sptr<Event> > * fifo){    myServiceManagerFifo = fifo;}EventSubject< Sptr<Event> > &   Service::getEventSubject(){    return ( mySubject );}const EventSubject< Sptr<Event> > &   Service::getEventSubject() const{    return ( mySubject );}void                    Service::setSignalAction(SignalAction * signalAction){    mySignalAction = signalAction;}                ReturnCode  	    Service::run(){    const string    fn("Service::run");    VLog    	    log(fn);    VDEBUG(log) << fn << ": " << myName << " starting." << VDEBUG_END(log);    ReturnCode	    rc = SUCCESS;    bool    	    done = false;    while ( !done )    {    	int numberMsgActive = 0;    	// Wait for activity.	//    	try	{    	    VVERBOSE(log)<< fn << ": before wait"	    	    	 << ", number msgs active = " << numberMsgActive			 << VVERBOSE_END(log);            numberMsgActive = block();    	    VVERBOSE(log) << fn << ": after wait"	    	    	  << ", number msgs active = " << numberMsgActive	    	    	  << VVERBOSE_END(log);	}	catch ( VException & exception )	{	    onVException(exception);	    continue;	}	catch ( ... )	{	    onException();	    continue;	}    	// Process the messages.	//    	try	{    	    done = processMessages(numberMsgActive, rc);	}	catch ( VException & exception )	{	    onVException(exception);	    continue;	}	catch ( ... )	{	    onException();	    continue;	}    }    VDEBUG(log) << fn << ": " << myName << " exiting"	    	<< ", rc = " << rc << VDEBUG_END(log);    return ( rc );}voidService::subscribe(EventObserver< Sptr<Event> > & observer){    const string    fn("Service::subscribe");    VLog    	    log(fn);        VDEBUG(log) << fn << ": observer = " << observer << VDEBUG_END(log);        mySubject.attach(observer);    VVERBOSE(log) << fn << ": subject = { " << mySubject << " }" << VVERBOSE_END(log);}void	    	    Service::unsubscribe(EventObserver< Sptr<Event> > & observer){    const string    fn("Service::unsubscribe");    VLog    	    log(fn);        VDEBUG(log) << fn << ": observer = " << observer << VDEBUG_END(log);        mySubject.detach(observer);    VVERBOSE(log) << fn << ": subject = { " << mySubject << " }" << VVERBOSE_END(log);}ostream &           Service::writeTo(ostream & out) const{    return ( out << myName << ", subject = " << mySubject );}const string &Service::name() const{    return ( myName );}ReturnCodeService::onStart(){    return ( SUCCESS );}ReturnCodeService::onStop(){    return ( SUCCESS );}ReturnCode	    	Service::onShutdown(){    return ( SUCCESS );}		void	    	Service::onVException(VException & exception){    const string    fn("Service::onVException");    VLog    	    log(fn);        VDEBUG(log) << fn << ": ignoring." << VDEBUG_END(log);}		void	    	Service::onException(){    const string    fn("Service::onException");    VLog    	    log(fn);        VDEBUG(log) << fn << ": doing a hardShutdown." << VDEBUG_END(log);    hardShutdown(!SUCCESS);}		void	    	Service::onSignalCaught(){    const string    fn("Service::onSignalCaught");    VLog    	    log(fn);        VDEBUG(log) << fn << ": doing a shutdown via signal." << VDEBUG_END(log);    hardShutdown(SUCCESS);}		bool	    Service::processMessages(int, ReturnCode & rc){    const string    fn("Service::processMessages");    VLog    	    log(fn);        bool	    done = false;    rc = SUCCESS;    while ( !done && getFifo().messageAvailable() )    {    	VVERBOSE(log) << fn << ": before getMessage." << VVERBOSE_END(log);    	Sptr<Event> event;    	try	{    	    event = getFifo().getNext();	}	catch ( ... )	{	    // We checked messageAvailable, so we shouldn't ever get here.	    //	    assert(0);	}    	Sptr<ControlEvent> ctrlEvent;    	ctrlEvent.dynamicCast(event);    	// Service control events detected. Call the appropriate	// Service callbacks.	//    	if ( ctrlEvent != 0 )    	{	    VDEBUG(log) << fn << ": event = { " << *ctrlEvent 		    	<< " }" << VDEBUG_END(log);    	    switch ( ctrlEvent->getType() )    	    {		case ControlEvent::START:		{		    start(ctrlEvent);		    break;		}		case ControlEvent::STOP:		{		    stop(ctrlEvent);		    break;		}		case ControlEvent::SHUTDOWN:		{		    rc = shutdown(ctrlEvent);		    done = true;		    break;		}		default:		{		    // Perhaps someone has derived off of the 		    // ControlEvent and wants to see it.		    //		    mySubject.setEvent(event);		    break;		}	    }    	}    	// Unknown event, give it to the EventSubject to distribute it	// to interested observers.	//	else	{	    mySubject.setEvent(event);	}    }    return ( done );}void	    	Service::hardShutdown(ReturnCode errorCode){    const string    fn("Service::hardShutdown");    VLog    	    log(fn);    VDEBUG(log) << fn << ": shutting down service"    	    	<< ", error = " << errorCode << VDEBUG_END(log);    shutdown(0);        ControlEvent * ctrlEvent         = new ControlEvent(ControlEvent::SHUTDOWN, getFifo());    ctrlEvent->setReturnCode(errorCode);    ctrlEvent->response();        Sptr<Event> shutdownEvent = ctrlEvent;    getServiceManagerFifo().add(shutdownEvent);}void	    	Service::start(Sptr<ControlEvent> startEvent){    const string    fn("Service::start");    VLog    	    log(fn);    ReturnCode      rc = SUCCESS;        FifoBase< Sptr<Event> > *	serviceMgrFifo = startEvent->getReplyFifo();    if ( !serviceMgrFifo || *serviceMgrFifo != getServiceManagerFifo() )    {    	VWARN(log)  << fn << ": received unathorized start event, event = "	    	    << *startEvent << VWARN_END(log);        rc = !SUCCESS;    }    else    {        rc = onStart();    }    startEvent->setReturnCode(rc);    startEvent->response();    Sptr<Event> event = startEvent;    serviceMgrFifo->add(event);    VDEBUG(log) << fn << ": returning start = " << *startEvent     	    	<< VDEBUG_END(log);}void	    	Service::stop(Sptr<ControlEvent> stopEvent){    const string    fn("Service::stop");    VLog    	    log(fn);        ReturnCode      rc = SUCCESS;        FifoBase< Sptr<Event> > *	serviceMgrFifo = stopEvent->getReplyFifo();        if ( !serviceMgrFifo || *serviceMgrFifo != getServiceManagerFifo() )    {    	VWARN(log)  << fn << ": received unathorized stop event, event = "	    	    << *stopEvent << VWARN_END(log);                            rc = !SUCCESS;    }    else    {        rc = onStop();    }    stopEvent->setReturnCode(rc);    stopEvent->response();        Sptr<Event> event = stopEvent;    serviceMgrFifo->add(event);    VDEBUG(log) << fn << ": returning stop = " << *stopEvent     	    	<< VDEBUG_END(log);}ReturnCode	    	Service::shutdown(Sptr<ControlEvent> shutdownEvent){    const string    fn("Service::shutdown");    VLog    	    log(fn);    if ( shutdownEvent == 0 )    {    	VDEBUG(log) << fn << ": hard shutdown." << VDEBUG_END(log);	return ( SUCCESS );    }        FifoBase< Sptr<Event> > *	serviceMgrFifo = shutdownEvent->getReplyFifo();        if ( !serviceMgrFifo || *serviceMgrFifo != getServiceManagerFifo() )    {    	VWARN(log)  << fn << ": received unathorized shutdown event, event = "	    	    << *shutdownEvent << VWARN_END(log);        return ( SUCCESS );    }        ReturnCode	rc = shutdownEvent->getReturnCode();    ReturnCode	onShutdownRC = onShutdown();    if ( rc == SUCCESS )    {	rc = onShutdownRC;    }        VDEBUG(log) << fn << ": recevied shutdown = " << *shutdownEvent 		<< ", rc = " << rc    	    	<< VDEBUG_END(log);    return ( rc );}void	    	Service::blockSignals(){    if ( mySignalAction )    {        Thread::self()->signalHandler().block(mySignalAction->signalSet());    }}		void	    	Service::unblockSignals(){    if ( mySignalAction )    {        Thread::self()->signalHandler().unblock(mySignalAction->signalSet());    }}	intService::block(){    const string    fn("Service::block");    VLog    	    log(fn);        unblockSignals();    int numberMsgActive = getFifo().block();    blockSignals();    if ( mySignalAction && mySignalAction->signalCaught() )    {	mySignalAction->reset();        onSignalCaught();    }    return ( numberMsgActive );}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -