Alluvium
Alluvium

Reputation: 23

Resource Management Design Patterns

Various APIs require calls to initialization and finalization methods. Most recently I've come across this while using the Python C++ API, where all API calls must be between calls to Py_Initialize and Py_FinalizeEx. My current solution is to put such calls at the beginning and end of the main method. This does not seem ideal, as it separates the actual usage of the API from it's resource management. That is, the software components which make API calls rely on the main method to acquire and destroy the resources.

Is there a pattern that is usually applied in such a scenario?

Here is what I'm currently doing.

int redirected(int argc, char *argv[]) {
    // Actual main method

    return 0;
}

int main(int argc, char *argv[]) {
    auto program = Py_DecodeLocale(argv[0], NULL);
    if (program)
        Py_SetProgramName(program);
    else
        throw new std::runtime_error("Py_SetProgramName");

    Py_Initialize();

    int errc = redirected(argc, argv);

    if (Py_FinalizeEx() < 0)
        throw new std::runtime_error("Py_FinalizeEx");

    PyMem_RawFree(program);

    return errc;
}

Upvotes: 2

Views: 469

Answers (1)

Matthieu Brucher
Matthieu Brucher

Reputation: 22023

The proper pattern in C++ is using RAII. And indeed, it's a very good question.

This means that the constructor of an object will acquire the resource and the destructor will release it. This way you ensure that the resource will always be freed when you get out of scope.

For Python, it would be:

class PyInit
{
public:
    PyInit() {Py_Initialize();}
    ~PyInit() {Py_Finalize();}
}

And then in main:

int main()
{
    PyInit pyinit;
    // using Python interpreter
    return 0;
}

Upvotes: 3

Related Questions