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*

Reply via email to