Philip Martin <philip.mar...@wandisco.com> writes: > handle_fetch (request=0x7ffff3e56038, response=0x7ffff3e918b8, > handler_baton=0x7ffff3e611e0, pool=0x7ffff3e6d028) > at ../src/subversion/libsvn_ra_serf/update.c:1152 > 1152 if (SERF_BUCKET_READ_ERROR(status)) > (gdb) p status > $13 = 0
So that's what happens when I interrupt the infinite loop, i.e. long after the first failure to read from the socket. If I catch the first socket read error then serf does supply an error to ra_serf: (gdb) serf_dechunk_read (bucket=0x7ffff3e92338, requested=8096, data=0x7fffffffd308, len=0x7fffffffd300) at buckets/dechunk_buckets.c:126 126 if (SERF_BUCKET_READ_ERROR(status)) (gdb) n 132 ctx->body_left -= *len; (gdb) 133 if (!ctx->body_left) { (gdb) 139 if (ctx->body_left && APR_STATUS_IS_EOF(status)) { (gdb) 140 return SERF_ERROR_TRUNCATED_HTTP_RESPONSE; (gdb) 184 } (gdb) serf_deflate_read (bucket=0x7ffff3e924b8, requested=8000, data=0x7fffffffd430, len=0x7fffffffd428) at buckets/deflate_buckets.c:260 260 if (SERF_BUCKET_READ_ERROR(ctx->stream_status)) { (gdb) 261 return ctx->stream_status; (gdb) p ctx->stream_status $5 = 120106 (gdb) n 388 } (gdb) serf_response_read (bucket=0x7ffff3e918b8, requested=8000, data=0x7fffffffd430, len=0x7fffffffd428) at buckets/response_buckets.c:412 412 if (SERF_BUCKET_READ_ERROR(rv)) (gdb) 413 return rv; (gdb) p rv $6 = 120106 (gdb) n 425 } So serf returned SERF_ERROR_TRUNCATED_HTTP_RESPONSE to ra_serf which responds by converting it to APR_EAGAIN: (gdb) handle_fetch (request=0x7ffff3e56038, response=0x7ffff3e918b8, handler_baton=0x7ffff3e611e0, pool=0x7ffff3e6d028) at ../src/subversion/libsvn_ra_serf/update.c:1152 1152 if (SERF_BUCKET_READ_ERROR(status)) (gdb) 1154 return svn_ra_serf__wrap_err(status, NULL); (gdb) 1221 } (gdb) handle_response (request=0x7ffff3e56038, response=0x7ffff3e918b8, handler=0x7ffff3e61220, serf_status=0x7fffffffd57c, scratch_pool=0x7ffff3e6d028) at ../src/subversion/libsvn_ra_serf/util.c:1391 1391 if (err (gdb) p err->apr_err $7 = 120106 (gdb) handle_response_cb (request=0x7ffff3e56038, response=0x7ffff3e918b8, baton=0x7ffff3e61220, scratch_pool=0x7ffff3e6d028) at ../src/subversion/libsvn_ra_serf/util.c:1425 1425 outer_status = save_error(handler->session, err); (gdb) 1426 if (!outer_status) (gdb) p outer_status $9 = 120106 (gdb) n 1430 if (APR_STATUS_IS_EOF(outer_status) || APR_STATUS_IS_EOF(inner_status)) (gdb) n 1443 else if (SERF_BUCKET_READ_ERROR(outer_status) (gdb) 1444 && handler->session->pending_error) (gdb) 1446 handler->discard_body = TRUE; /* Discard further data */ (gdb) 1447 handler->done = TRUE; /* Mark as done */ (gdb) 1448 handler->scheduled = FALSE; (gdb) 1449 outer_status = APR_EAGAIN; /* Exit context loop */ (gdb) 1452 return outer_status; So ra_serf hands back APR_EAGAIN to serf which responds by converting it to APR_SUCCESS: read_from_connection (conn=0x7ffff3e73028) at outgoing.c:1131 1131 if (APR_STATUS_IS_ECONNRESET(status) || (gdb) 1132 APR_STATUS_IS_ECONNABORTED(status) || (gdb) 1150 if (APR_STATUS_IS_EAGAIN(status)) { (gdb) 1155 if (request_or_data_pending(&request, conn) && !request) { (gdb) 1159 status = APR_SUCCESS; (gdb) 1232 apr_pool_destroy(tmppool); (gdb) 1233 return status; -- Philip