Change pointer to shared_ptr#671
Conversation
|
These are great changes IMO! As you noted, @bam241, requiring use of a One thought might be to have a raw pointer to a DagMC::DagMC(Interface* mb_impl, double overlap_tolerance, double p_numerical_precision) {
// if we arent handed a moab instance, create one
if (nullptr == mb_impl) {
mb_shared = std::shared_ptr<Core>();
MBI = mb_shared.get();
} else {
MBI = mb_impl;
}
// make new GeomTopoTool and GeomQueryTool
...
}If the pointer is passed in, we won't delete it on cleanup but if we did create it, the Does that sound plausible or am I missing something? Clarification: In the example above |
|
Adding to the comment above, if we go this route I think it would be good for us to include a constructor that takes in a |
src/dagmc/DagMC.cpp
Outdated
| // make new GeomTopoTool and GeomQueryTool | ||
| GTT = new moab::GeomTopoTool(MBI, false); | ||
| GQT = new moab::GeomQueryTool(GTT, overlap_tolerance, p_numerical_precision); | ||
| GTT = std::shared_ptr<GeomTopoTool> (new GeomTopoTool(MBI.get(), false)); |
There was a problem hiding this comment.
Should these be unique_ptr's as those objects are going to carry state that is related directly to calls that have been made on this DagMC object (e.g. init_obbs)?
|
|
||
| // delete dagmc | ||
| delete dagmc; | ||
| delete mbi; |
|
@gonuke @pshriwise @makeclean this should be ready for an other round of review |
pshriwise
left a comment
There was a problem hiding this comment.
A couple of thoughts on returning shared pointers from the DagMC interface. I think we're going to run into trouble making sure they don't cause problems at this point. We'll get there someday though hopefully.
src/dagmc/DagMC.hpp
Outdated
| GeomTopoTool* geom_tool() {return GTT;} | ||
| [[ deprecated("Replaced by std::shared_ptr<GeomTopoTool> geom_tool_ptr()") ]] | ||
| GeomTopoTool* geom_tool() {return GTT.get();} | ||
| std::shared_ptr<GeomTopoTool> geom_tool_ptr() {return GTT;} |
There was a problem hiding this comment.
We need to be careful about passing back shared pointers for these objects. In the case where we've created the MOAB instance, these objects aren't guaranteed to be useable beyond the life of the DAGMC object.
// populates the MBI_shared_ptr and sets MBI
std::unique_ptr<DagMC> dag = std::make_unique<DagMC>();
moab::Errorcode rval = dag->load_file("test.h5m");
MB_CHK_ERR(rval);
rval = dag->init_OBBTree();
MB_CHK_ERR(rval);
// retrieve a shared_ptr GTT from the DagMC instance
std::shared_ptr<GeomTopoTool> gtt = dag->geom_tool_ptr();
// MBI_shared_ptr is cleaned up and the MOAB instance is destroyed as intended
dag.reset();
// the GTT shared_ptr is still available, but any call that relies on it's underlying MBI pointer will fail
rval = gtt->check_model(); // will segfault
MB_CHK_ERR(rval);I think it would be better to keep only the geom_tool() method for now.
There was a problem hiding this comment.
it make sense the only shared_ptr we shall return is the MBI one....
the other one depends on each other through the raw pointer not the shared pointer, so we can't guaranty they will be working outside of the DagMC instance....
src/dagmc/DagMC.hpp
Outdated
| /** Get the instance of MOAB used by functions in this file. */ | ||
| [[ deprecated("Replaced by std::shared_ptr<Interface> moab_instance_ptr()") ]] | ||
| Interface* moab_instance() {return MBI;} | ||
| std::shared_ptr<Interface> moab_instance_ptr() {return MBI_shared_ptr;} |
There was a problem hiding this comment.
This method is also a little inconsistent with our current design. What if the deprecated constructor is used and this object is a nullptr?
Co-Authored-By: Patrick Shriwise <pshriwise@gmail.com>
|
This is really close I think. Any luck with making the |
Sadly not, I have a error message with the (when I googled it, the easy work around was to use a |
|
@pshriwise @gonuke @makeclean Do we want to throw a warning if someone if trying to get it and it is not defined, or is returning a |
|
I'd prefer there be some kind of warning/error here. If we're returning an empty shared pointer and know it, it seems as though we should give some kind of indication about that. Honestly, I think we should throw a runtime error, but I'd take a warning too :) |
…ared_ptr and only instanciated as a raw pointer
| std::shared_ptr<Interface> moab_instance_sptr() { | ||
| if (nullptr == MBI_shared_ptr) | ||
| std::runtime_error("MBI instance is not defined as a shared pointer !"); | ||
| return MBI_shared_ptr; | ||
| } |
There was a problem hiding this comment.
Added a runtime_error when trying to return the MBI instance as a shared_ptr when it has been provided as a direct pointer. (It has been implemented in the Header, as it is fairly simple, I can move it to the cpp file if you prefer)
|
A remaining identified issue (that existed before) is if returning This would also occur before this change tho... (Does not mean we should not fix it, but might be outside of the scope of this PR...) |
|
Agreed @bam241. Let's make an issue for that and move forward for now. I'll merge this today if there are no other comments/concerns. |
|
Thanks again for tackling this @bam241! |
addressing comment from #660:
Originally posted by @PullRequest-Agent in #660
Targeting declaration and deletion of pointers in DagMC() (see DAGMC.cpp L64)
Not sure we want to change the API (constructor of DagMC class) but I was not able to have shared_ptr<> in the body of the DagMC class and still accept a normal pointer for the Interface* because when declaring the point outside of the DagMC instance, one need to delete it, but the ownership of the Interface* has been transferred to the shared_ptr<> which is suppose to take care of the deallocation.
But it is not obvious without looking at the
DagMC.cppsource code that you should not deallocate your own pointer.More over if the Interface* object would probably been deallocated after deleting the DagMC object which will be problematic if you want to used it ( Interface*) after the DagMC deletion....
I created a separate PR for this one, as it will be simpler to review, and I think it might need some discussion about how to address this.
To make that change I was not able to find an other implementation, so I see only 2 solutions:
pointerand delete