Bug 49024

Summary: pycairo freezes apache + mod_wsgi
Product: pycairo Reporter: keen <keen.browne>
Component: generalAssignee: Steve Chaplin <d74n5pohf9>
Status: RESOLVED INVALID QA Contact:
Severity: normal    
Priority: medium    
Version: unspecified   
Hardware: x86-64 (AMD64)   
OS: Linux (All)   
Whiteboard:
i915 platform: i915 features:

Description keen 2012-04-20 12:43:07 UTC
When integrating pycairo into a django app pycairo, we discovered pycairo can deadlock the web server by holding the global interpreter lock.  This happens because, by default, mod_wsgi creates a 'subinterpreter' to run the application. For example, in a django view function do something like this:

from cStringIO import StringIO  # both StringIO and cStringIO cause the issue
import cairo

out = StringIO()
surface = cairo.SVGSurface(out, 10, 10)

surface.finish()  # deadlock

The offending lines of code appear to be in surface.c
static cairo_status_t
_write_func (void *closure, const unsigned char *data, unsigned int length) { ... }

I think the calls to PyGILState_Ensure and PyGILState_Release need to be replaced with calls to the Py_BEGIN_ALLOW_THREADS and Py_END_ALLOW_THREADS macros

WORKAROUND
set WSGIApplicationGroup %{GLOBAL} in the apache conf.
It's also a good idea to reduce the deadlock timeout of the WSGIDaemonProcess.
Comment 1 Steve Chaplin 2012-08-04 05:27:29 UTC
I thought that using PyGILState_Ensure and PyGILState_Release was the recommended method when you are using an external C library to write to a file.
Py_BEGIN_ALLOW_THREADS may work better. If you can test it, and report back with the results, that would be useful.
Comment 2 Christoph Reiter 2017-07-05 15:36:34 UTC
I don't know how sub-interpreters affect GIL related code, but the current code looks correct to me and the proposed solution definitely does not. If someone happens to end up here and has some additional information or examples please file a bug @ https://github.com/pygobject/pycairo/issues

Use of freedesktop.org services, including Bugzilla, is subject to our Code of Conduct. How we collect and use information is described in our Privacy Policy.