I'm trying to write an adapter to Flow Graph that imitates a pipeline-like synchronous function call. But I don't understand how to block and wait for the output for a specific token. Calling wait_for_all
on the graph doesn't help as I don't need to wait for all values. Can anybody suggest a solution?
template <typename TOutput, typename TInput>
class FlowPathAdapter {
public:
TOutput operator()(const TInput& val) {
m_input->try_put(val);
TOutput result;
// What should be done here to ensure that
// m_output returns the result corresponding to this specific token?
m_output->try_get(result);
return result;
}
private:
// input and output are connected in some graph constructed outside the adapter
std::shared_ptr<tbb::flow::receiver<TInput>> m_input;
std::shared_ptr<tbb::flow::sender<TOutput>> m_output;
};
Waiting is generally avoided in TBB; waiting is non-productive.
The timing of task execution in TBB is also not guaranteed because we depend on the OS for scheduling. That is, doing out-of-band signaling such as an atomic operation will not occur after the message from a node is forwarded, so the result will not be ready. You would also have to use a
queue_node
or other buffering node to hold the result.Given that, if you wish to do an explicit wait you can make a
function_node
that receives the final answer, assigns it to a result location, and does a signal to tell the result is ready. (the signal should be an atomic to enforce fencing.) Your other task can spin-wait on the atomic. Or you can use a condition variable.Regards, Chris