-
Notifications
You must be signed in to change notification settings - Fork 66
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for bringing us up-to-date on this front @bam241! A few suggestions on creating the std::shared_ptr
's.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 mbi; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎉
@gonuke @pshriwise @makeclean this should be ready for an other round of review |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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
Interface* moab_instance() {return MBI;} | ||
std::shared_ptr<Interface> moab_instance_ptr() {return MBI_shared_ptr;} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 <[email protected]>
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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks again @bam241 for taking this on! It's a much-needed update. Hopefully we can start to convert some of our other classes to these more modern practices in the future.
@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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@svalinn/dagmc I am now satisfied with this.
I updated the news to reflect our discussion.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.cpp
source 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:
pointer
and delete