Skip to content

Commit

Permalink
fix #177: avoid GIL deadlock
Browse files Browse the repository at this point in the history
  • Loading branch information
mindhells committed Oct 29, 2020
1 parent e94cbce commit 3e3893b
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 15 deletions.
8 changes: 0 additions & 8 deletions fract4d/c/fract4dc/calcargs.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
#include "Python.h"
#include <mutex>

#include "calcargs.h"

Expand All @@ -18,36 +17,30 @@ calc_args::calc_args()
params = new double[N_PARAMS];
}

static std::mutex ref_count_mutex;

void calc_args::set_cmap(PyObject *pycmap_)
{
pycmap = pycmap_;
cmap = colormaps::cmap_fromcapsule(pycmap);
const std::lock_guard<std::mutex> lock(ref_count_mutex);
Py_XINCREF(pycmap);
}

void calc_args::set_pfo(PyObject *pypfo_)
{
pypfo = pypfo_;
pfo = (loaders::pf_fromcapsule(pypfo))->pfo;
const std::lock_guard<std::mutex> lock(ref_count_mutex);
Py_XINCREF(pypfo);
}

void calc_args::set_im(PyObject *pyim_)
{
pyim = pyim_;
im = images::image_fromcapsule(pyim);
const std::lock_guard<std::mutex> lock(ref_count_mutex);
Py_XINCREF(pyim);
}
void calc_args::set_site(PyObject *pysite_)
{
pysite = pysite_;
site = sites::site_fromcapsule(pysite);
const std::lock_guard<std::mutex> lock(ref_count_mutex);
Py_XINCREF(pysite);
}

Expand All @@ -57,7 +50,6 @@ calc_args::~calc_args()
#ifdef DEBUG_CREATION
fprintf(stderr, "%p : CA : DTOR\n", this);
#endif
const std::lock_guard<std::mutex> lock(ref_count_mutex);
Py_XDECREF(pycmap);
Py_XDECREF(pypfo);
Py_XDECREF(pyim);
Expand Down
31 changes: 24 additions & 7 deletions fract4d/c/fract4dc/calcs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,14 @@ namespace calcs {

if (cargs->asynchronous)
{
auto &site = *cargs->site;
site.interrupt();
site.wait();
site.start();
site.set_thread(std::thread(calculation_thread, cargs));
std::thread t([cargs](){
auto &site = *cargs->site;
site.interrupt();
site.wait();
site.start();
site.set_thread(std::thread(calculation_thread, cargs));
});
t.detach();
}
else
{
Expand All @@ -76,6 +79,21 @@ namespace calcs {
}
}

struct GIL_guard {
PyGILState_STATE state;
bool active;
GIL_guard():
state(PyGILState_Ensure()), active(true) {}
void restore()
{
PyGILState_Release(state);
active = false;
}
~GIL_guard()
{
if (active) restore();
}
};

void * calculation_thread(calc_args *args)
{
Expand All @@ -94,9 +112,8 @@ void * calculation_thread(calc_args *args)
#ifdef DEBUG_THREADS
std::cerr << args << " : CA : ENDCALC(" << std::this_thread::get_id() << ")\n";
#endif
PyGILState_STATE gstate = PyGILState_Ensure();
GIL_guard e;
delete args;
PyGILState_Release(gstate);
return NULL;
}

Expand Down
1 change: 1 addition & 0 deletions fract4d/c/fract4dmodule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -651,6 +651,7 @@ PyInit_fract4dc(void)
return NULL;
}

// todo: check this https://docs.python.org/3/c-api/init.html#c.PyEval_InitThreads
PyEval_InitThreads();

/* expose some constants */
Expand Down

0 comments on commit 3e3893b

Please sign in to comment.