Trying to update my working copy I observed svn spinning on the CPU forever. Attaching with gdb showed that it was stuck in an endless loop inside svn_ra_serf__handle_xml_parser().
Below is the code. The problem was that serf_bucket_read() returned zero bytes but also indicated success. If that happens the loop never terminates. I suppose this code was written with the assumption that reading from the socket would always block until data is available? This does not seem to happen in my case. Maybe serf is doing something wrong when it opens the socket? I'm using serf-0.7.x from the branch as of June 21. while (1) { const char *data; apr_size_t len; status = serf_bucket_read(response, PARSE_CHUNK_SIZE, &data, &len); if (SERF_BUCKET_READ_ERROR(status)) { return svn_error_wrap_apr(status, NULL); } /* Note: once the callbacks invoked by inject_to_parser() sets the PAUSED flag, then it will not be cleared. write_to_pending() will only save the content. Logic outside of serf_context_run() will clear that flag, as appropriate, along with processing the content that we have placed into the PENDING buffer. We want to save arriving content into the PENDING structures if the parser has been paused, or we already have data in there (so the arriving data is appended, rather than injected out of order) */ #ifdef DISABLE_THIS_FOR_NOW if (ctx->paused || HAS_PENDING_DATA(ctx->pending)) { err = write_to_pending(ctx, data, len, pool); } else #endif { err = inject_to_parser(ctx, data, len, &sl); if (err) { /* Should have no errors if IGNORE_ERRORS is set. */ SVN_ERR_ASSERT(!ctx->ignore_errors); } } if (err) { XML_ParserFree(ctx->xmlp); add_done_item(ctx); return svn_error_return(err); } if (APR_STATUS_IS_EAGAIN(status)) { return svn_error_wrap_apr(status, NULL); } if (APR_STATUS_IS_EOF(status)) { if (ctx->pending != NULL) ctx->pending->network_eof = TRUE; /* We just hit the end of the network content. If we have nothing in the PENDING structures, then we're completely done. */ if (!HAS_PENDING_DATA(ctx->pending)) { /* Ignore the return status. We just don't care. */ (void) XML_Parse(ctx->xmlp, NULL, 0, 1); XML_ParserFree(ctx->xmlp); add_done_item(ctx); } return svn_error_wrap_apr(status, NULL); } /* feed me! */ }