tags:

views:

260

answers:

3

Hi, I've got a library written in C++ which I wrap using SWIG and use in python. Generally there is one class with few methods. The problem is that calling these methods may be time consuming - they may hang my application (GIL is not released when calling these methods). So my question is:

what is the simplest way to release GIL for these method calls?

(I understand that if I used C library I could wrap this with some additional C code, but here I use C++ and classes)

+1  A: 

You can use the same API call as for C. No difference. Include "python.h" and call the appoproate function.

Also, see if SWIG doesn't have a typemap or something to indicate that the GIL shuold not be held for a specific function.

Marcus Lindblom
+1  A: 

Not having any idea what SWIG is I'll attempt an answer anyway :)

Use something like this to release/acquire the GIL:

class GILReleaser {
    GILReleaser() : save(PyEval_SaveThread()) {}

    ~GILReleaser() {
        PyEval_RestoreThread(save);
    }

    PyThreadState* save;
};

And in the code-block of your choosing, utilize RAII to release/acquire GIL:

{
    GILReleaser releaser;
    // ... Do stuff ...
}
Henrik Gustafsson
+2  A: 

The real problem is that SWIG is not documented well (I saw hints to use changelog for searching ;) ).

Ok, I found out that I can do inline functions in SWIG and use macros to release/acquire GIL, it looks like this:

%inline %{
    void wrappedFunction(OriginalObject *o, <parameters>) {
    Py_BEGIN_ALLOW_THREADS
    o->originalFunction(<parameters>);
    Py_END_ALLOW_THREADS
}
%}

This function is not present in original C++, but available in python module. This is (almost) exactly what I wanted. (what I would like is to wrap original method like python decorator does)

uhzzre