Skip to content

Commit

Permalink
Prevent nested Python function calling Matlab #26
Browse files Browse the repository at this point in the history
  • Loading branch information
mducle committed Oct 3, 2024
1 parent c1b4379 commit 88ba6f8
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 6 deletions.
24 changes: 18 additions & 6 deletions src/libpymcr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ namespace libpymcr {

py::object matlab_env::feval(const std::u16string &funcname, py::args args, py::kwargs& kwargs) {
// Calls Matlab function
if (_in_evaluation) {
throw std::runtime_error("Cannot call Matlab from a nested Python function.");
}
_in_evaluation = true;
const size_t nlhs = 0;
// Clears the streams
_m_output.get()->str(std::basic_string<char16_t>());
Expand All @@ -60,14 +64,20 @@ namespace libpymcr {
size_t nargout = _parse_inputs(m_args, args, kwargs);
// Release the GIL to call Matlab (PyBind automatically acquires GIL in all defined functions)
py::gil_scoped_release gil_release;
if (nargout == 1) {
if (m_args.size() == 1) {
outputs.push_back(evalloop(_lib->fevalAsync(funcname, m_args[0], _m_output_buf, _m_error_buf)));
try {
if (nargout == 1) {
if (m_args.size() == 1) {
outputs.push_back(evalloop(_lib->fevalAsync(funcname, m_args[0], _m_output_buf, _m_error_buf)));
} else {
outputs.push_back(evalloop(_lib->fevalAsync(funcname, m_args, _m_output_buf, _m_error_buf)));
}
} else {
outputs.push_back(evalloop(_lib->fevalAsync(funcname, m_args, _m_output_buf, _m_error_buf)));
outputs = evalloop(_lib->fevalAsync(funcname, nargout, m_args, _m_output_buf, _m_error_buf));
}
} else {
outputs = evalloop(_lib->fevalAsync(funcname, nargout, m_args, _m_output_buf, _m_error_buf));
}
catch(...) {
_in_evaluation = false;
throw;
}
// Re-aquire the GIL
py::gil_scoped_acquire gil_acquire;
Expand Down Expand Up @@ -97,6 +107,7 @@ namespace libpymcr {
}
// Now clear temporary Matlab arrays created from Numpy array data inputs
_converter.clear_py_cache();
_in_evaluation = false;
return retval;
}

Expand All @@ -113,6 +124,7 @@ namespace libpymcr {
_app = matlab::cpplib::initMATLABApplication(mode, options);
_lib = matlab::cpplib::initMATLABLibrary(_app, ctfname);
_converter = pymat_converter(pymat_converter::NumpyConversion::COPY);
_in_evaluation = false;
}


Expand Down
1 change: 1 addition & 0 deletions src/libpymcr.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ namespace libpymcr {
pymat_converter _converter;
size_t _parse_inputs(std::vector<matlab::data::Array>& m_args, py::args py_args, py::kwargs& py_kwargs);
template <class T> T evalloop(matlab::cpplib::FutureResult<T> resAsync);
bool _in_evaluation;
public:
py::object feval(const std::u16string &funcname, py::args args, py::kwargs& kwargs);
py::object call(py::args args, py::kwargs& kwargs);
Expand Down

0 comments on commit 88ba6f8

Please sign in to comment.