Jim Gallacher wrote:
Volodya wrote:

On Mon, Jan 30, 2006 at 09:40:39PM -0500, Graham Dumpleton wrote:

Graham Dumpleton wrote ..

Extending the above code as:

   Py_BEGIN_ALLOW_THREADS;
rc = ap_get_brigade(c->input_filters, bb, mode, APR_BLOCK_READ, bufsize);
   Py_END_ALLOW_THREADS;

   if (! APR_STATUS_IS_SUCCESS(rc)) {
       PyErr_SetObject(PyExc_IOError,
                       PyString_FromString("Connection read error"));
       return NULL;
   }

   /* Return empty string if no buckets. Can be caused by EAGAIN. */
   if (APR_BRIGADE_EMPTY(bb)) {
       return PyString_FromString("");
   }

seems to fix the problem. Ie., use call to APR_BRIGADE_EMPTY(bb) to check
whether any new buckets added and returning empty string if not.


Okay, this may work, but the EAGAIN propogating backup as an empty
string to Python can cause a tight loop to occur where calls are going
out and back into Python code. This will occur until something is read
or an error occurs.

To avoid the back and forth, another option may be:

   while (APR_BRIGADE_EMPTY(bb)) {
       Py_BEGIN_ALLOW_THREADS;
rc = ap_get_brigade(c->input_filters, bb, mode, APR_BLOCK_READ, bufsize);
       Py_END_ALLOW_THREADS;

       if (! APR_STATUS_IS_SUCCESS(rc)) {
           PyErr_SetObject(PyExc_IOError,
PyString_FromString("Connection read error"));
           return NULL;
       }
   }



Graham,

this code runs smoothly, i.e. no segfaults, all tests passed:
FreeBSD 4.9:


That's good news. I still wonder why we are seeing this problem in 3.2 and 3.1.4 though.

And what I meant to say was "and *NOT* in 3.1.4".

Jim

Reply via email to