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!