virtual bool connectionAdded( base::ChannelElementBase::shared_ptr channel_input, ConnPolicy const& policy ) { // Initialize the new channel with last written data if requested // (and available) // This this the input channel element of the whole connection typename base::ChannelElement<T>::shared_ptr channel_el_input = static_cast< base::ChannelElement<T>* >(channel_input.get()); if (written) { typename internal::AssignableDataSource<T>::shared_ptr last_written_value = this->last_written_value; if (last_written_value) { T sample = last_written_value->get(); if ( channel_el_input->data_sample(sample) ) { if ( policy.init ) return channel_el_input->write(sample); return true; } else { Logger::In in("OutputPort"); log(Error) << "Failed to pass data sample to data channel. Aborting connection."<<endlog(); return false; } } } // even if we're not written, test the connection with a default sample. return channel_el_input->data_sample( T() ); }
virtual bool inputReady() { if ( mqReady(read_sample, this) ) { typename base::ChannelElement<T>::shared_ptr output = this->getOutput(); assert(output); output->data_sample(read_sample->rvalue()); return true; } return false; }
bool do_init(typename base::ChannelElement<T>::param_t sample, const internal::ConnectionManager::ChannelDescriptor& descriptor) { typename base::ChannelElement<T>::shared_ptr output = boost::static_pointer_cast< base::ChannelElement<T> >(descriptor.get<1>()); if (output->data_sample(sample)) return false; else { log(Error) << "A channel of port " << getName() << " has been invalidated during setDataSample(), it will be removed" << endlog(); return true; } }
/** * Signal will cause a read-write cycle to transfer the * data from the data/buffer element to the message queue * and vice versa. * * Note: this virtual function is a bit abused. For a sending * MQ, signal triggers a direct read on the data element. * For a receiving MQ, signal is used by the dispatcher thread * to provoque a read from the MQ and forward it to the next * channel element. * * In the sending case, signal could trigger a dispatcher thread * that does the read/write cycle, but that seems only causing overhead. * The receiving case must use a thread which blocks on all mq * file descriptors. * @return true in case the forwarding could be done, false otherwise. */ bool signal() { // copy messages into channel if (mis_sender) { // this read should always succeed since signal() means // 'data available in a data element'. typename base::ChannelElement<T>::shared_ptr input = this->getInput(); if( input && input->read(read_sample->set(), false) == NewData ) return this->write(read_sample->rvalue()); } else { typename base::ChannelElement<T>::shared_ptr output = this->getOutput(); if (output && mqRead(read_sample)) return output->write(read_sample->rvalue()); } return false; }