PLearn 0.1
|
00001 // -*- C++ -*- 00002 00003 // Poll.cc 00004 // 00005 // Copyright (C) 2005 Christian Hudon 00006 // Copyright (C) 2007 Xavier Saint-Mleux, ApSTAT Technologies inc. 00007 // 00008 // Redistribution and use in source and binary forms, with or without 00009 // modification, are permitted provided that the following conditions are met: 00010 // 00011 // 1. Redistributions of source code must retain the above copyright 00012 // notice, this list of conditions and the following disclaimer. 00013 // 00014 // 2. Redistributions in binary form must reproduce the above copyright 00015 // notice, this list of conditions and the following disclaimer in the 00016 // documentation and/or other materials provided with the distribution. 00017 // 00018 // 3. The name of the authors may not be used to endorse or promote 00019 // products derived from this software without specific prior written 00020 // permission. 00021 // 00022 // THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 00023 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 00024 // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 00025 // NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00026 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 00027 // TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00028 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00029 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00030 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00031 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00032 // 00033 // This file is part of the PLearn library. For more information on the PLearn 00034 // library, go to the PLearn Web site at www.plearn.org 00035 00036 /* ******************************************************* 00037 * $Id: Poll.cc 8837 2008-04-19 01:25:41Z lamblin $ 00038 ******************************************************* */ 00039 00040 // Authors: Christian Hudon 00041 00045 #include "Poll.h" 00046 #include <plearn/base/plerror.h> 00047 #include <plearn/base/PrUtils.h> 00048 #include <plearn/io/PrPStreamBuf.h> 00049 #include <plearn/math/random.h> 00050 00051 namespace PLearn { 00052 using namespace std; 00053 00054 void Poll::setStreamsToWatch(const vector<PStream>& streams) { 00055 m_streams_to_watch.clear(); 00056 m_poll_descriptors.resize(streams.size()); 00057 00058 int i = 0; 00059 for (vector<PStream>::const_iterator it = streams.begin(); 00060 it != streams.end(); ++it, ++i) 00061 { 00062 PStreamBuf* st = *it; 00063 PrPStreamBuf* pr_st = dynamic_cast<PrPStreamBuf*>(st); 00064 if (!pr_st) 00065 PLERROR("Poll::setStreamsToWatch: only PrPStreamBuf streams supported!"); 00066 00067 m_streams_to_watch.push_back(*it); 00068 m_poll_descriptors[i].fd = pr_st->in; 00069 m_poll_descriptors[i].in_flags = PR_POLL_READ; 00070 } 00071 00072 } 00073 00074 int Poll::waitForEvents(uint32_t timeout, bool shuffle_events_) 00075 { 00076 if (m_poll_descriptors.size() == 0) 00077 PLERROR("Poll::waitforEvents: called with no streams to watch."); 00078 00079 shuffle_events= shuffle_events_; 00080 if(shuffle_events)//shuffle index vec if necessary 00081 { 00082 shuffled_index= TVec<int>(0, m_poll_descriptors.size()-1, 1); 00083 shuffleElements(shuffled_index); 00084 } 00085 00086 m_next_unexamined_event = 0; 00087 00088 //first, check for non-empty buffers (ready to read) 00089 int nevents= 0; 00090 for(unsigned int i= 0; i < m_poll_descriptors.size(); ++i) 00091 if(!m_streams_to_watch[i]->inbufEmpty()) 00092 ++nevents; 00093 00094 if(nevents > 0)//if we already have some events, poll w/ no wait 00095 timeout= PR_INTERVAL_NO_WAIT; 00096 00097 //poll underlying streams 00098 last_n_poll_events= PR_Poll(&m_poll_descriptors[0], PRIntn(m_poll_descriptors.size()), timeout); 00099 00100 if(last_n_poll_events < 0) 00101 PLERROR((string("Poll::waitForEvents: poll error: ") + getPrErrorString()).c_str()); 00102 00103 nevents= 0;// now count _all_ events (non-empty buffers + stream polling) 00104 for(unsigned int i= 0; i < m_poll_descriptors.size(); ++i) 00105 if ((last_n_poll_events > 0 00106 && m_poll_descriptors[i].out_flags & PR_POLL_READ) 00107 || !m_streams_to_watch[i]->inbufEmpty()) 00108 ++nevents; 00109 00110 return nevents; 00111 } 00112 00113 PStream Poll::getNextPendingEvent() { 00114 while (m_next_unexamined_event < m_poll_descriptors.size()) 00115 { 00116 int i = m_next_unexamined_event++; 00117 if(shuffle_events) 00118 i= shuffled_index[i]; 00119 if ((last_n_poll_events > 0 00120 && m_poll_descriptors[i].out_flags & PR_POLL_READ) 00121 || !m_streams_to_watch[i]->inbufEmpty()) 00122 return m_streams_to_watch[i]; 00123 } 00124 00125 PLERROR("Poll::getNextPendingEvent: called with no more pending events!"); 00126 // We never reach this because of the PLERROR. Used to silence 00127 // a gcc warning. 00128 return PStream(); 00129 } 00130 00131 00132 } // end of namespace PLearn 00133 00134 00135 /* 00136 Local Variables: 00137 mode:c++ 00138 c-basic-offset:4 00139 c-file-style:"stroustrup" 00140 c-file-offsets:((innamespace . 0)(inline-open . 0)) 00141 indent-tabs-mode:nil 00142 fill-column:79 00143 End: 00144 */ 00145 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=79 :