Package: python-zbar
Version: 0.10+doc-10
Severity: wishlist
Tags: upstream patch
As discussed in http://sourceforge.net/p/zbar/bugs/48/ the Python
bindings for zbar do not support threading, meaning it's not possible to
build multithreaded Python tools supporting asynchronous scanning. There
is an upstream fix at:
http://sourceforge.net/p/zbar/code/ci/1c14e19910e96fe132897db8343b24179265f3ef
which I have added on top of the zbar 0.10+doc-9 package and confirmed
fixes the issue I see; I attach it to this bug report as well (I dropped
it in debian/patches/ and added it to debian/patches/series for
building).
Please consider including this fix with the next package upload. Thanks.
-- System Information:
Debian Release: jessie/sid
APT prefers testing
APT policy: (900, 'testing'), (800, 'unstable'), (500, 'testing-updates'),
(1, 'experimental')
Architecture: amd64 (x86_64)
Foreign Architectures: i386
Kernel: Linux 3.17.0+ (SMP w/4 CPU cores)
Locale: LANG=en_GB.utf8, LC_CTYPE=en_GB.utf8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
Versions of packages python-zbar depends on:
ii libc6 2.19-11
ii libjpeg8 8d1-2
ii libv4l-0 1.6.0-1+b1
ii libzbar0 0.10+doc-10
ii python 2.7.8-1
python-zbar recommends no packages.
python-zbar suggests no packages.
-- no debconf information
--- a/python/processor.c 2009-10-23 19:16:44.000000000 +0100
+++ b/python/processor.c 2014-07-29 18:22:52.706154561 +0100
@@ -36,15 +36,24 @@
PyObject *args,
PyObject *kwds)
{
- static char *kwlist[] = { NULL };
- if(!PyArg_ParseTupleAndKeywords(args, kwds, "", kwlist))
+ static char *kwlist[] = { "enable_threads", NULL };
+ int threaded = -1;
+ if(!PyArg_ParseTupleAndKeywords(args, kwds, "|O&", kwlist,
+ object_to_bool, &threaded))
+ return(NULL);
+
+#ifndef WITH_THREAD
+ if(threaded > 0 &&
+ PyErr_WarnEx(NULL, "threading requested but not available", 1))
return(NULL);
+ threaded = 0;
+#endif
zbarProcessor *self = (zbarProcessor*)type->tp_alloc(type, 0);
if(!self)
return(NULL);
- self->zproc = zbar_processor_create(0/*FIXME*/);
+ self->zproc = zbar_processor_create(threaded);
zbar_processor_set_userdata(self->zproc, self);
if(!self->zproc) {
Py_DECREF(self);
@@ -228,7 +237,11 @@
object_to_timeout, &timeout))
return(NULL);
- int rc = zbar_processor_user_wait(self->zproc, timeout);
+ int rc = -1;
+ Py_BEGIN_ALLOW_THREADS
+ rc = zbar_processor_user_wait(self->zproc, timeout);
+ Py_END_ALLOW_THREADS
+
if(rc < 0)
return(zbarErr_Set((PyObject*)self));
return(PyInt_FromLong(rc));
@@ -245,7 +258,11 @@
object_to_timeout, &timeout))
return(NULL);
- int rc = zbar_process_one(self->zproc, timeout);
+ int rc = -1;
+ Py_BEGIN_ALLOW_THREADS
+ rc = zbar_process_one(self->zproc, timeout);
+ Py_END_ALLOW_THREADS
+
if(rc < 0)
return(zbarErr_Set((PyObject*)self));
return(PyInt_FromLong(rc));
@@ -265,7 +282,11 @@
if(zbarImage_validate(img))
return(NULL);
- int n = zbar_process_image(self->zproc, img->zimg);
+ int n = -1;
+ Py_BEGIN_ALLOW_THREADS
+ n = zbar_process_image(self->zproc, img->zimg);
+ Py_END_ALLOW_THREADS
+
if(n < 0)
return(zbarErr_Set((PyObject*)self));
return(PyInt_FromLong(n));
@@ -275,6 +296,9 @@
process_handler (zbar_image_t *zimg,
const void *userdata)
{
+ PyGILState_STATE gstate;
+ gstate = PyGILState_Ensure();
+
zbarProcessor *self = (zbarProcessor*)userdata;
assert(self);
assert(self->handler);
@@ -285,7 +309,7 @@
img = zbarImage_FromImage(zimg);
if(!img) {
PyErr_NoMemory();
- return;
+ goto done;
}
}
else
@@ -299,8 +323,17 @@
PyTuple_SET_ITEM(args, 2, self->closure);
PyObject *junk = PyObject_Call(self->handler, args, NULL);
- Py_XDECREF(junk);
+ if(junk)
+ Py_DECREF(junk);
+ else {
+ PySys_WriteStderr("in ZBar Processor data_handler:\n");
+ assert(PyErr_Occurred());
+ PyErr_Print();
+ }
Py_DECREF(args);
+
+done:
+ PyGILState_Release(gstate);
}
static PyObject*