Skip to content

Commit

Permalink
Handle sharing of ExtensibleRate among copies of ReactionRateDelegator
Browse files Browse the repository at this point in the history
  • Loading branch information
speth committed Sep 11, 2022
1 parent bf1e2b4 commit d198841
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 13 deletions.
13 changes: 4 additions & 9 deletions include/cantera/base/Delegator.h
Expand Up @@ -8,6 +8,7 @@

#include "cantera/base/global.h"
#include "cantera/base/ctexceptions.h"
#include "cantera/base/ExtensionManager.h"
#include <array>
#include <list>

Expand Down Expand Up @@ -101,12 +102,6 @@ namespace Cantera
class Delegator
{
public:
~Delegator() {
for (auto& func : m_cleanup_funcs) {
func();
}
}

//! Set delegates for member functions with the signature `void()`.
void setDelegate(const std::string& name, const std::function<void()>& func,
const std::string& when)
Expand Down Expand Up @@ -249,8 +244,8 @@ class Delegator
*m_funcs_sz_csr[name] = makeDelegate(func, when, m_base_sz_csr[name]);
}

void addCleanupFunc(const std::function<void()>& func) {
m_cleanup_funcs.push_back(func);
void holdExternalHandle(const shared_ptr<ExternalHandle>& handle) {
m_handles.push_back(handle);
}

protected:
Expand Down Expand Up @@ -490,7 +485,7 @@ class Delegator
//! @}

//! Cleanup functions to be called from the destructor
std::list<std::function<void()>> m_cleanup_funcs;
std::list<shared_ptr<ExternalHandle>> m_handles;
};

}
Expand Down
8 changes: 8 additions & 0 deletions include/cantera/base/ExtensionManager.h
Expand Up @@ -24,6 +24,14 @@ class ExtensionManager
};
};

//! A base class for managing the lifetime of an external object, such as a Python
//! object used by a Delegator
class ExternalHandle
{
public:
virtual ~ExternalHandle() = default;
};

}

#endif
20 changes: 16 additions & 4 deletions src/extensions/PythonExtensionManager.cpp
Expand Up @@ -16,6 +16,20 @@ using namespace std;

namespace {

class PythonHandle : public Cantera::ExternalHandle
{
public:
explicit PythonHandle(PyObject* obj) : m_obj(obj) {}

~PythonHandle() {
Py_XDECREF(m_obj);
}

private:
PyObject* m_obj;
};


std::string getPythonExceptionInfo()
{
if (!PyErr_Occurred()) {
Expand Down Expand Up @@ -126,10 +140,8 @@ void PythonExtensionManager::registerPythonRateBuilder(
//! Call setParameters after the delegated functions have been connected
delegator->setParameters(params, units);

// Make the delegator responsible for eventually deleting the Python object
Py_IncRef(extRate);
delegator->addCleanupFunc([extRate]() { Py_DecRef(extRate); });

// The delegator is responsible for eventually deleting the Python object
delegator->holdExternalHandle(make_shared<PythonHandle>(extRate));
return delegator.release();
};
ReactionRateFactory::factory()->reg(rateName, builder);
Expand Down

0 comments on commit d198841

Please sign in to comment.