blocxx
|
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