blocxx

SelectEngine.cpp

Go to the documentation of this file.
00001 /*******************************************************************************
00002 * Copyright (C) 2005, Vintela, Inc. All rights reserved.
00003 * Copyright (C) 2006, Novell, Inc. All rights reserved.
00004 * 
00005 * Redistribution and use in source and binary forms, with or without
00006 * modification, are permitted provided that the following conditions are met:
00007 * 
00008 *     * Redistributions of source code must retain the above copyright notice,
00009 *       this list of conditions and the following disclaimer.
00010 *     * Redistributions in binary form must reproduce the above copyright
00011 *       notice, this list of conditions and the following disclaimer in the
00012 *       documentation and/or other materials provided with the distribution.
00013 *     * Neither the name of 
00014 *       Vintela, Inc., 
00015 *       nor Novell, Inc., 
00016 *       nor the names of its contributors or employees may be used to 
00017 *       endorse or promote products derived from this software without 
00018 *       specific prior written permission.
00019 * 
00020 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
00021 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00022 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00023 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
00024 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
00025 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
00026 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
00027 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
00028 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00029 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00030 * POSSIBILITY OF SUCH DAMAGE.
00031 *******************************************************************************/
00032 
00033 
00039 #include "blocxx/BLOCXX_config.h"
00040 #include "blocxx/SelectEngine.hpp"
00041 #include "blocxx/Select.hpp"
00042 #include "blocxx/ExceptionIds.hpp"
00043 #include "blocxx/Timeout.hpp"
00044 #include "blocxx/TimeoutTimer.hpp"
00045 
00046 namespace BLOCXX_NAMESPACE
00047 {
00048 
00049 BLOCXX_DEFINE_EXCEPTION_WITH_ID(Select);
00051 void
00052 SelectEngine::addSelectableObject(const Select_t& obj,
00053    const SelectableCallbackIFCRef& cb, SelectableCallbackIFC::EEventType eventType)
00054 {
00055    m_table.insert(std::make_pair(obj, Data(cb, eventType)));
00056 }
00057 
00059 bool 
00060 SelectEngine::removeSelectableObject(const Select_t& obj, SelectableCallbackIFC::EEventType eventType)
00061 {
00062    return m_table.erase(obj);
00063 }
00064 
00066 void
00067 SelectEngine::go(const Timeout& timeout)
00068 {
00069    TimeoutTimer timer(timeout);
00070    timer.start();
00071    m_stopFlag = false;
00072    do
00073    {
00074       Select::SelectObjectArray selObjs;
00075       typedef SortedVectorMap<Select_t, Data>::const_iterator citer_t;
00076       for (citer_t iter = m_table.begin(); iter != m_table.end(); ++iter)
00077       {
00078          Select::SelectObject so(iter->first);
00079          if (iter->second.eventType & SelectableCallbackIFC::E_READ_EVENT)
00080          {
00081             so.waitForRead = true;
00082          }
00083          if (iter->second.eventType & SelectableCallbackIFC::E_WRITE_EVENT)
00084          {
00085             so.waitForWrite = true;
00086          }
00087          selObjs.push_back(so);
00088       }
00089       
00090       if (selObjs.empty())
00091       {
00092          return;
00093       }
00094 
00095       int selected = Select::selectRW(selObjs, timer.asTimeout());
00096       if (selected == Select::SELECT_ERROR)
00097       {
00098          BLOCXX_THROW_ERRNO_MSG(SelectException, "Select Error");
00099       }
00100       else if (selected == Select::SELECT_TIMEOUT)
00101       {
00102          BLOCXX_THROW(SelectException, "Select Timeout");
00103       }
00104       else
00105       {
00106          for (size_t i = 0; i < selObjs.size() && selected > 0; ++i)
00107          {
00108             const Select::SelectObject& selObj(selObjs[i]);
00109             if (selObj.readAvailable || selObj.writeAvailable)
00110             {
00111                --selected;
00112                typedef SortedVectorMap<Select_t, Data>::iterator iter_t;
00113                iter_t iter = m_table.find(selObj.s);
00114                if (selObj.readAvailable)
00115                {
00116                   iter->second.callback->selected(iter->first, SelectableCallbackIFC::E_READ_EVENT);
00117                }
00118                if (selObj.writeAvailable)
00119                {
00120                   iter->second.callback->selected(iter->first, SelectableCallbackIFC::E_WRITE_EVENT);
00121                }
00122             }
00123          }
00124       }
00125       timer.resetOnLoop();
00126    } while (!m_stopFlag);
00127 }
00129 void
00130 SelectEngine::stop()
00131 {
00132    m_stopFlag = true;
00133 }
00134 
00136 SelectEngineStopper::SelectEngineStopper(SelectEngine& engine)
00137    : SelectableCallbackIFC()
00138    , m_engine(engine)
00139 {
00140 }
00141 
00143 void 
00144 SelectEngineStopper::doSelected(Select_t& selectedObject, EEventType eventType)
00145 {
00146    m_engine.stop();
00147 }
00148    
00149 } // end namespace BLOCXX_NAMESPACE
00150