PLearn 0.1
Poll.cc
Go to the documentation of this file.
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 :
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines