reSIProcate/stack  9694
EventStackThread.cxx
Go to the documentation of this file.
00001 #include <climits>
00002 
00003 #include "resip/stack/EventStackThread.hxx"
00004 #include "resip/stack/SipStack.hxx"
00005 //#include "resip/stack/SipMessage.hxx"
00006 //#include "rutil/SelectInterruptor.hxx"
00007 //#include "resip/stack/FdPoll.hxx"
00008 
00009 #include "rutil/Logger.hxx"
00010 #define RESIPROCATE_SUBSYSTEM Subsystem::SIP
00011 
00012 using namespace resip;
00013 
00014 /****************************************************************
00015  *
00016  * EventThreadInterruptor
00017  *
00018  ****************************************************************/
00019 
00020 EventThreadInterruptor::EventThreadInterruptor(FdPollGrp& pollGrp)
00021   : mPollGrp(pollGrp)
00022 {
00023    mPollItemHandle = mPollGrp.addPollItem(getReadSocket(), FPEM_Read, this);
00024 }
00025 
00026 EventThreadInterruptor::~EventThreadInterruptor()
00027 {
00028    mPollGrp.delPollItem(mPollItemHandle);
00029 }
00030 
00031 /****************************************************************
00032  *
00033  * EventStackThread
00034  *
00035  ****************************************************************/
00036 
00037 EventStackThread::EventStackThread(EventThreadInterruptor& si,
00038       FdPollGrp& pollGrp)
00039    : mIntr(si), mPollGrp(pollGrp)
00040 {
00041 }
00042 
00043 EventStackThread::EventStackThread(SipStack& stack, EventThreadInterruptor& si,
00044       FdPollGrp& pollGrp)
00045    : mIntr(si), mPollGrp(pollGrp)
00046 {
00047     addStack(stack);
00048 }
00049 
00050 
00051 EventStackThread::~EventStackThread()
00052 {
00053    //InfoLog (<< "EventStackThread::~EventStackThread()");
00054 }
00055 
00056 void
00057 EventStackThread::addStack(SipStack& stack)
00058 {
00059     mStacks.push_back(&stack);
00060 }
00061 
00062 void
00063 EventStackThread::thread()
00064 {
00065    while (!isShutdown())
00066    {
00067       unsigned waitMs = getTimeTillNextProcessMS();
00068       if ( waitMs > INT_MAX )
00069          waitMs = INT_MAX;
00070       StackList::iterator it;
00071       for ( it=mStacks.begin(); it!=mStacks.end(); ++it)
00072       {
00073          SipStack *ss = *it;
00074          unsigned wms = ss->getTimeTillNextProcessMS();
00075          if ( wms < waitMs )
00076             waitMs = wms;
00077          // NOTE: In theory, we could early-out when waitMs gets to zero
00078          // but I fear the stack may depend upon doing real-work in the query.
00079       }
00080       mPollGrp.waitAndProcess((int)waitMs);
00081       for ( it=mStacks.begin(); it!=mStacks.end(); ++it)
00082       {
00083          SipStack *ss = *it;
00084          ss->processTimers();
00085       }
00086       afterProcess();
00087    }
00088    InfoLog (<< "Shutting down stack thread");
00089 }
00090 
00091 void
00092 EventStackThread::shutdown()
00093 {
00094    ThreadIf::shutdown();
00095    mIntr.interrupt();
00096 }
00097 
00098 unsigned int
00099 EventStackThread::getTimeTillNextProcessMS() const
00100 {
00101    return 10000;
00102 }
00103 
00104 void
00105 EventStackThread::afterProcess()
00106 {
00107 }
00108 
00109 
00110 /****************************************************************
00111  *
00112  * EventStackSimpleMgr
00113  *
00114  * This is a helper class that constructs the thread-related
00115  * classes in the appropriate order, and destructs them when done.
00116  * It is to help save typing in simple applications.
00117  *
00118  ****************************************************************/
00119 
00120 EventStackSimpleMgr::EventStackSimpleMgr(const char *implName)
00121    : mPollGrp(0), mIntr(0), mThread(0), mStack(0)
00122 {
00123    mPollGrp = FdPollGrp::create(implName);
00124    mIntr = new EventThreadInterruptor(*mPollGrp);
00125    mThread = new EventStackThread(*mIntr, *mPollGrp);
00126 }
00127 
00128 EventStackSimpleMgr::~EventStackSimpleMgr()
00129 {
00130    release();
00131 }
00132 
00133 void
00134 EventStackSimpleMgr::setOptions(SipStackOptions& options)
00135 {
00136    options.mPollGrp = mPollGrp;
00137    options.mAsyncProcessHandler = mIntr;
00138 }
00139 
00140 
00141 SipStack&
00142 EventStackSimpleMgr::createStack(SipStackOptions& options)
00143 {
00144    setOptions(options);
00145    mStack = new SipStack(options);
00146    mThread->addStack(*mStack);
00147    return *mStack;
00148 }
00149 
00150 void
00151 EventStackSimpleMgr::release() {
00152    if ( mThread )
00153    {
00154       delete mThread; mThread = NULL;
00155    }
00156    if ( mStack ) {
00157       // we only delete the stack if we created, not if externally created
00158       delete mStack; mStack = NULL;
00159    }
00160    if ( mIntr )
00161    {
00162       delete mIntr; mIntr = NULL;
00163    }
00164    if ( mPollGrp )
00165    {
00166       delete mPollGrp; mPollGrp = NULL;
00167    }
00168 }
00169 
00170 /* ====================================================================
00171  * The Vovida Software License, Version 1.0
00172  *
00173  * Copyright (c) 2000 Vovida Networks, Inc.  All rights reserved.
00174  *
00175  * Redistribution and use in source and binary forms, with or without
00176  * modification, are permitted provided that the following conditions
00177  * are met:
00178  *
00179  * 1. Redistributions of source code must retain the above copyright
00180  *    notice, this list of conditions and the following disclaimer.
00181  *
00182  * 2. Redistributions in binary form must reproduce the above copyright
00183  *    notice, this list of conditions and the following disclaimer in
00184  *    the documentation and/or other materials provided with the
00185  *    distribution.
00186  *
00187  * 3. The names "VOCAL", "Vovida Open Communication Application Library",
00188  *    and "Vovida Open Communication Application Library (VOCAL)" must
00189  *    not be used to endorse or promote products derived from this
00190  *    software without prior written permission. For written
00191  *    permission, please contact vocal@vovida.org.
00192  *
00193  * 4. Products derived from this software may not be called "VOCAL", nor
00194  *    may "VOCAL" appear in their name, without prior written
00195  *    permission of Vovida Networks, Inc.
00196  *
00197  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
00198  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00199  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
00200  * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
00201  * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
00202  * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
00203  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00204  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00205  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
00206  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00207  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
00208  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
00209  * DAMAGE.
00210  *
00211  * ====================================================================
00212  *
00213  * This software consists of voluntary contributions made by Vovida
00214  * Networks, Inc. and many individuals on behalf of Vovida Networks,
00215  * Inc.  For more information on Vovida Networks, Inc., please see
00216  * <http://www.vovida.org/>.
00217  *
00218  * vi: set shiftwidth=3 expandtab:
00219  */