I would like to be able to dynamically add/remove nodes to/from a Flow Graph.
As far as I understand this is possible by simply using make_edge/remove_edge while the graph is running.
However, from the documentation I recall reading that a node cannot be destroyed until wait_for_all has been called on the graph. Which makes removing nodes from the graph a bit tricky as in my application I either don't call wair_for_all or when I call it I have incremented its ref count so that it doesn't return until the application ends.
Have I misunderstood the documentation? i.e. is it possible to destroy nodes after they have been removed from the graph even without calling wait_for_all on the graph?
The documentation for graph says "Destruction of flow graph nodes before calling wait_for_all on their associated graph object has undefined behavior and can lead to program failure.". Removing a node and destroying it are the same thing. If you wonder whether an isolated node can be removed, I would think that there might be outstanding tasks related to the Message Passing Protocol, so no... That also makes it unlikely that edges can be dynamically removed: where did you read that?
Disclaimer:I think that the documentation needs some TLC, so that will be my excuse if I'm mistaken. :-)
From what I can see in the code.
overwrite_node do not actually need to be connected to the graph (assuming that it always has a value). So what I want to achieve is possible using those nodes, i.e. using overwrite_node:s to connect different graphs? Even though it is undefined according to the documentation.
Maybe you can find something here.
It shows that you can connect multiple graphs together and give each a different task_group_context.
But I freely admit that I don't know that much about flow graph, and again I blame the state of the documentation.
Unfortunately that does not seem to help. Still need to wait for all graph instances in order to perform any changes.
The problem seems to have to do with life time management of the nodes. Where there are two cases where there can be a problem:
1. A task is actively using a node.
2. A node is in the predecessors set.
These are only guaranteed to be false if all nodes are inactive and only then can a node be deleted.
On could perform a remove_edge call. As long as you don't destroy the node. However, it will only succeed if the node is in the successors set.
The only solution as far as I can see is to invent some kind of reference counting scheme using some sort of node wrapper which keeps track if a node wants to be removed from the graph.
Curiously enough. It seems safe to ADD edges.
Well, for now I think I am going with using overwrite_node:s and setting a "off" flags for node bodies to stop them and release internal memory.
I will simply leak the tbb flow nodes until my application runs out of memory (which should take long enough).
I have to say that TBB graph remains quite mysterious to me, and I keep blaming the documentation, insofar as it exists. Surely it's feasible to do better than requiring potential users to find a Dr. Dobb's article here and a blog there...