Sebastian Theophil wrote:
Please note this is not a rhetoric question: how do you know when you explicitly destroy a CObject that you leave no dangling boost::shared_ptrs to it?
[long explanation snipped] OK, thank you very much for the explanation. Sorry about having kept challenging your design, but I really couldn't see how you were in the situation you are. Now it's clear to me.
If the CChart has a multi index container of owning references to data labels, the problem I've described could result. If the multi_index_container is cleared and each reference is released, the CDataLabel is destroyed. During clear() you would have a stack trace like this:
multi_index_container::clear() - delete_node(root()) - destroy(node*) - ~owned_ref< CDataLabel > - ~CDataLabel -> and at this point the half-destructed reference is still part of the multi_index_container. Because it is half-destructed, the ordering criterion of the index may be violated and the CDataLabel cannot make a lookup on the container[...]
Yes, as you said and I confirmed erase() inside clear() does not work. It is not easy to make it work without greatly affecting the performance of clear(): the implementation of the latter takes advantage of the fact that all nodes must be deleted at once to do it in the most straightforward way, without bothering to keep the internal data structures consistent during the process. But you can circumvent this simply by using erase(begin(),end()) instead of clear(), because erase() is reentrant. To automate this, you can have your custom container deriving from multi_index_container defined as this: class my_container:public multi_index_container<...> { ~my_container() { erase(begin(),end()); } } Does this help? Joaquín M López Muñoz Telefónica, Investigación y Desarrollo -- View this message in context: http://www.nabble.com/-multi-index--Container-not-safe-against-reentrant-cle... Sent from the Boost - Users mailing list archive at Nabble.com.