template < typename IN_PORT_TYPE, typename OUT_PORT_TYPE > int randomizer_base::_transformerServiceFunction( typename std::vector< gr_istream< IN_PORT_TYPE > > &istreams , typename std::vector< gr_ostream< OUT_PORT_TYPE > > &ostreams ) { typedef typename std::vector< gr_istream< IN_PORT_TYPE > > _IStreamList; typedef typename std::vector< gr_ostream< OUT_PORT_TYPE > > _OStreamList; boost::mutex::scoped_lock lock(serviceThreadLock); if ( validGRBlock() == false ) { // create our processing block, and setup property notifiers createBlock(); LOG_DEBUG( randomizer_base, " FINISHED BUILDING GNU RADIO BLOCK"); } //process any Stream ID changes this could affect number of io streams processStreamIdChanges(); if ( !validGRBlock() || istreams.size() == 0 || ostreams.size() == 0 ) { LOG_WARN( randomizer_base, "NO STREAMS ATTACHED TO BLOCK..." ); return NOOP; } _input_ready.resize( istreams.size() ); _ninput_items_required.resize( istreams.size() ); _ninput_items.resize( istreams.size() ); _input_items.resize( istreams.size() ); _output_items.resize( ostreams.size() ); // // RESOLVE: need to look at forecast strategy, // 1) see how many read items are necessary for N number of outputs // 2) read input data and see how much output we can produce // // // Grab available data from input streams // typename _OStreamList::iterator ostream; typename _IStreamList::iterator istream = istreams.begin(); int nitems=0; for ( int idx=0 ; istream != istreams.end() && serviceThread->threadRunning() ; idx++, istream++ ) { // note this a blocking read that can cause deadlocks nitems = istream->read(); if ( istream->overrun() ) { LOG_WARN( randomizer_base, " NOT KEEPING UP WITH STREAM ID:" << istream->streamID ); } if ( istream->sriChanged() ) { // RESOLVE - need to look at how SRI changes can affect Gnu Radio BLOCK state LOG_DEBUG( randomizer_base, "SRI CHANGED, STREAMD IDX/ID: " << idx << "/" << istream->pkt->streamID ); setOutputStreamSRI( idx, istream->pkt->SRI ); } } LOG_TRACE( randomizer_base, "READ NITEMS: " << nitems ); if ( nitems <= 0 && !_istreams[0].eos() ) { return NOOP; } bool eos = false; int nout = 0; bool workDone = false; while ( nout > -1 && serviceThread->threadRunning() ) { eos = false; nout = _forecastAndProcess( eos, istreams, ostreams ); if ( nout > -1 ) { workDone = true; // we chunked on data so move read pointer.. istream = istreams.begin(); for ( ; istream != istreams.end(); istream++ ) { int idx=std::distance( istreams.begin(), istream ); // if we processed data for this stream if ( _input_ready[idx] ) { size_t nitems = 0; try { nitems = gr_sptr->nitems_read( idx ); } catch(...){} if ( nitems > istream->nitems() ) { LOG_WARN( randomizer_base, "WORK CONSUMED MORE DATA THAN AVAILABLE, READ/AVAILABLE " << nitems << "/" << istream->nitems() ); nitems = istream->nitems(); } istream->consume( nitems ); LOG_TRACE( randomizer_base, " CONSUME READ DATA ITEMS/REMAIN " << nitems << "/" << istream->nitems()); } } gr_sptr->reset_read_index(); } // check for not enough data return if ( nout == -1 ) { // check for end of stream istream = istreams.begin(); for ( ; istream != istreams.end() ; istream++) { if ( istream->eos() ) { eos=true; } } if ( eos ) { LOG_TRACE( randomizer_base, "EOS SEEN, SENDING DOWNSTREAM " ); _forecastAndProcess( eos, istreams, ostreams); } } } if ( eos ) { istream = istreams.begin(); for ( ; istream != istreams.end() ; istream++ ) { int idx=std::distance( istreams.begin(), istream ); LOG_DEBUG( randomizer_base, " CLOSING INPUT STREAM IDX:" << idx ); istream->close(); } // close remaining output streams ostream = ostreams.begin(); for ( ; eos && ostream != ostreams.end(); ostream++ ) { int idx=std::distance( ostreams.begin(), ostream ); LOG_DEBUG( randomizer_base, " CLOSING OUTPUT STREAM IDX:" << idx ); ostream->close(); } } // // set the read pointers of the GNU Radio Block to start at the beginning of the // supplied buffers // gr_sptr->reset_read_index(); LOG_TRACE( randomizer_base, " END OF TRANSFORM SERVICE FUNCTION....." << noutput_items ); if ( nout == -1 && eos == false && !workDone ) { return NOOP; } else { return NORMAL; } }
template < typename IN_PORT_TYPE > int vector_sink_s_base::_analyzerServiceFunction( typename std::vector< gr_istream< IN_PORT_TYPE > > &istreams ) { typedef typename std::vector< gr_istream< IN_PORT_TYPE > > _IStreamList; boost::mutex::scoped_lock lock(serviceThreadLock); if ( validGRBlock() == false ) { // create our processing block createBlock(); LOG_DEBUG( vector_sink_s_base, " FINISHED BUILDING GNU RADIO BLOCK"); } // process any Stream ID changes this could affect number of io streams processStreamIdChanges(); if ( !validGRBlock() || istreams.size() == 0 ) { LOG_WARN(vector_sink_s_base, "NO STREAMS ATTACHED TO BLOCK..." ); return NOOP; } // resize data vectors for passing data to GR_BLOCK object _input_ready.resize( istreams.size() ); _ninput_items_required.resize( istreams.size()); _ninput_items.resize( istreams.size()); _input_items.resize(istreams.size()); _output_items.resize(0); // // RESOLVE: need to look at forecast strategy, // 1) see how many read items are necessary for N number of outputs // 2) read input data and see how much output we can produce // // // Grab available data from input streams // typename _IStreamList::iterator istream = istreams.begin(); int nitems=0; for ( int idx=0 ; istream != istreams.end() && serviceThread->threadRunning() ; idx++, istream++ ) { // note this a blocking read that can cause deadlocks nitems = istream->read(); if ( istream->overrun() ) { LOG_WARN( vector_sink_s_base, " NOT KEEPING UP WITH STREAM ID:" << istream->streamID ); } // RESOLVE issue when SRI changes that could affect the GNU Radio BLOCK if ( istream->sriChanged() ) { LOG_DEBUG( vector_sink_s_base, "SRI CHANGED, STREAMD IDX/ID: " << idx << "/" << istream->pkt->streamID ); } } LOG_TRACE( vector_sink_s_base, "READ NITEMS: " << nitems ); if ( nitems <= 0 && !_istreams[0].eos() ) return NOOP; bool exitServiceFunction = false; bool eos = false; int nout = 0; while ( nout > -1 && !exitServiceFunction && serviceThread->threadRunning() ) { eos = false; nout = _forecastAndProcess( eos, istreams ); if ( nout > -1 ) { // we chunked on data so move read pointer.. istream = istreams.begin(); for ( ; istream != istreams.end(); istream++ ) { int idx=std::distance( istreams.begin(), istream ); // if we processed data for this stream if ( _input_ready[idx] ) { size_t nitems = 0; try { nitems = gr_sptr->nitems_read( idx ); } catch(...){} if ( nitems > istream->nitems() ) { LOG_WARN( vector_sink_s_base, "WORK CONSUMED MORE DATA THAN AVAILABLE, READ/AVAILABLE " << nitems << "/" << istream->nitems() ); nitems = istream->nitems(); } istream->consume( nitems ); LOG_TRACE( vector_sink_s_base, " CONSUME READ DATA ITEMS/REMAIN " << nitems << "/" << istream->nitems()); } } gr_sptr->reset_read_index(); } // check for not enough data return if ( nout == -1 ) { // check for end of stream istream = istreams.begin(); for ( ; istream != istreams.end() ; istream++) if ( istream->eos() ) eos=true; if ( eos ) { LOG_TRACE( vector_sink_s_base, " DATA NOT READY, EOS:" << eos ); _forecastAndProcess( eos, istreams ); } exitServiceFunction = true; } } if ( eos ) { istream = istreams.begin(); for ( ; istream != istreams.end() ; istream++) { int idx=std::distance( istreams.begin(), istream ); LOG_TRACE( vector_sink_s_base, " CLOSING INPUT STREAM IDX:" << idx ); istream->close(); } } // // set the read pointers of the GNU Radio Block to start at the beginning of the // supplied buffers // gr_sptr->reset_read_index(); LOG_TRACE( vector_sink_s_base, " END OF ANALYZER SERVICE FUNCTION....." << noutput_items ); if ( nout == -1 && eos == false ) return NOOP; else return NORMAL; }