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:

  Apache/2.0.50 (prefork) Python/2.3.4
  Apache/2.0.55 (prefork) Python/2.4.2

Thanks!

Reply via email to