FreeBSD/contrib/subversion/subversion/libsvn_ra_serf/update.c
/* Delaying wrapping reponse handler, to avoid creating too many
   requests to deliver efficiently */
Delaying wrapping reponse handler, to avoid creating too many
requests to deliver efficiently
Delaying wrapping reponse handler to avoid creating too many requests to deliver efficiently
static svn_error_t *
update_delay_handler(serf_request_t *request,
                     serf_bucket_t *response,
                     void *handler_baton,
                     apr_pool_t *scratch_pool)
{
  update_delay_baton_t *udb = handler_baton;
  apr_status_t status;
  apr_pool_t *iterpool = NULL;
  if (! udb->spillbuf)
    {
      if (udb->report->send_all_mode)
        {
          return svn_error_trace(udb->inner_handler(request, response,
                                                    udb->inner_handler_baton,
                                                    scratch_pool));
        }
      while ((udb->report->num_active_fetches + udb->report->num_active_propfinds)
                 < REQUEST_COUNT_TO_RESUME)
        {
          const char *data;
          apr_size_t len;
          svn_boolean_t at_eof = FALSE;
          svn_error_t *err;
          status = serf_bucket_read(response, PARSE_CHUNK_SIZE, &data, &len);
          if (SERF_BUCKET_READ_ERROR(status))
            return svn_ra_serf__wrap_err(status, NULL);
          else if (APR_STATUS_IS_EOF(status))
            udb->report->report_received = at_eof = TRUE;
          if (!iterpool)
            iterpool = svn_pool_create(scratch_pool);
          else
            svn_pool_clear(iterpool);
          if (len == 0 && !at_eof)
            return svn_ra_serf__wrap_err(status, NULL);
          err = process_buffer(udb, request, data, len, at_eof,
                               serf_request_get_alloc(request),
                               iterpool);
          if (err && SERF_BUCKET_READ_ERROR(err->apr_err))
            return svn_error_trace(err);
          else if (err && APR_STATUS_IS_EAGAIN(err->apr_err))
            {
              svn_error_clear(err); 
            }
          else if (err && (APR_STATUS_IS_EOF(err->apr_err)))
            {
              svn_pool_destroy(iterpool);
              return svn_error_trace(err); 
            }
          else
            {
              return svn_error_trace(err);
            }
        }
      udb->spillbuf = svn_spillbuf__create(SPILLBUF_BLOCKSIZE,
                                           SPILLBUF_MAXBUFFSIZE,
                                           udb->report->pool);
    }
  do
    {
      const char *data;
      apr_size_t len;
      status = serf_bucket_read(response, 8*PARSE_CHUNK_SIZE, &data, &len);
      if (!SERF_BUCKET_READ_ERROR(status))
        SVN_ERR(svn_spillbuf__write(udb->spillbuf, data, len, scratch_pool));
    }
  while (status == APR_SUCCESS);
  if (APR_STATUS_IS_EOF(status))
    udb->report->report_received = TRUE;
  if (status)
    return svn_ra_serf__wrap_err(status, NULL);
  else
    return SVN_NO_ERROR;
}
static svn_error_t * update_delay_handler ( serf_request_t * request , serf_bucket_t * response , void * handler_baton , apr_pool_t * scratch_pool ) { update_delay_baton_t * udb = handler_baton ; apr_status_t status ; apr_pool_t * iterpool = NULL ; if ( ! udb -> spillbuf ) { if ( udb -> report -> send_all_mode ) { return svn_error_trace ( udb -> inner_handler ( request , response , udb -> inner_handler_baton , scratch_pool ) ) ; } while ( ( udb -> report -> num_active_fetches + udb -> report -> num_active_propfinds ) < REQUEST_COUNT_TO_RESUME ) { const char * data ; apr_size_t len ; svn_boolean_t at_eof = FALSE ; svn_error_t * err ; status = serf_bucket_read ( response , PARSE_CHUNK_SIZE , & data , & len ) ; if ( SERF_BUCKET_READ_ERROR ( status ) ) return svn_ra_serf__wrap_err ( status , NULL ) ; else if ( APR_STATUS_IS_EOF ( status ) ) udb -> report -> report_received = at_eof = TRUE ; if ( ! iterpool ) iterpool = svn_pool_create ( scratch_pool ) ; else svn_pool_clear ( iterpool ) ; if ( len == 0 && ! at_eof ) return svn_ra_serf__wrap_err ( status , NULL ) ; err = process_buffer ( udb , request , data , len , at_eof , serf_request_get_alloc ( request ) , iterpool ) ; if ( err && SERF_BUCKET_READ_ERROR ( err -> apr_err ) ) return svn_error_trace ( err ) ; else if ( err && APR_STATUS_IS_EAGAIN ( err -> apr_err ) ) { svn_error_clear ( err ) ; } else if ( err && ( APR_STATUS_IS_EOF ( err -> apr_err ) ) ) { svn_pool_destroy ( iterpool ) ; return svn_error_trace ( err ) ; } else { return svn_error_trace ( err ) ; } } udb -> spillbuf = svn_spillbuf__create ( SPILLBUF_BLOCKSIZE , SPILLBUF_MAXBUFFSIZE , udb -> report -> pool ) ; } do { const char * data ; apr_size_t len ; status = serf_bucket_read ( response , 8 * PARSE_CHUNK_SIZE , & data , & len ) ; if ( ! SERF_BUCKET_READ_ERROR ( status ) ) SVN_ERR ( svn_spillbuf__write ( udb -> spillbuf , data , len , scratch_pool ) ) ; } while ( status == APR_SUCCESS ) ; if ( APR_STATUS_IS_EOF ( status ) ) udb -> report -> report_received = TRUE ; if ( status ) return svn_ra_serf__wrap_err ( status , NULL ) ; else return SVN_NO_ERROR ; }
Delaying wrapping reponse handler, to avoid creating too many
requests to deliver efficiently
Delaying wrapping reponse handler to avoid creating too many requests to deliver efficiently
/* Easy out... We only have one request, so avoid everything and just
             call the inner handler.

             We will always get in the loop (below) on the first chunk, as only
             the server can get us in true send-all mode */ /* Throttling is working ok */ /* No buffering was necessary */ /* SERF_ERROR_WAIT_CONN should be impossible? */ /* Let's start using the spill infrastructure */ /* Read everything we can to a spillbuffer */ /* ### What blocksize should we pass? */ /* We handle feeding the data from the main context loop, which will be right
     after processing the pending data */