Author: rhuijben
Date: Thu Aug  5 09:21:20 2010
New Revision: 982512

URL: http://svn.apache.org/viewvc?rev=982512&view=rev
Log:
Remove the last SVN_ERR_MALFUNCTION_NO_RETURN() from ra_serf, by updating
another callback to allow returning svn_error_t * instances.

* subversion/libsvn_ra_serf/ra_serf.h
  (svn_ra_serf__response_error_t): Return svn_error_t *

* subversion/libsvn_ra_serf/update.c
  (cancel_fetch): Update prototype to match callback and use a normal
    malfunction instead of the NO_RETURN variant for a currenly unreachable
    code path.

* subversion/libsvn_ra_serf/util.c
  (handle_response): Stop implementing serf_response_handler_t and return
    an svn_error_t * instead. Also add a serf_status argument to allow
    passing some serf internal result codes without creating an svn_error_t.

  (handle_response_cb): New function.

  (setup_request_cb): Rename to ...
  (setup_request): ... this and use handle_response_cb instead of 
handle_response.
  (setup_request): Rename to ...
  (setup_request_cb): ... this, as this is the real callback.

  (svn_ra_serf__request_create,
   svn_ra_serf__priority_request_create): Update callers.

Modified:
    subversion/trunk/subversion/libsvn_ra_serf/ra_serf.h
    subversion/trunk/subversion/libsvn_ra_serf/update.c
    subversion/trunk/subversion/libsvn_ra_serf/util.c

Modified: subversion/trunk/subversion/libsvn_ra_serf/ra_serf.h
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_serf/ra_serf.h?rev=982512&r1=982511&r2=982512&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_ra_serf/ra_serf.h (original)
+++ subversion/trunk/subversion/libsvn_ra_serf/ra_serf.h Thu Aug  5 09:21:20 
2010
@@ -457,7 +457,7 @@ typedef svn_error_t *
                                           apr_pool_t *pool);
 
 /* Callback for when a response has an error. */
-typedef apr_status_t
+typedef svn_error_t *
 (*svn_ra_serf__response_error_t)(serf_request_t *request,
                                  serf_bucket_t *response,
                                  int status_code,

Modified: subversion/trunk/subversion/libsvn_ra_serf/update.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_serf/update.c?rev=982512&r1=982511&r2=982512&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_ra_serf/update.c (original)
+++ subversion/trunk/subversion/libsvn_ra_serf/update.c Thu Aug  5 09:21:20 2010
@@ -692,7 +692,7 @@ headers_fetch(serf_bucket_t *headers,
   return SVN_NO_ERROR;
 }
 
-static apr_status_t
+static svn_error_t *
 cancel_fetch(serf_request_t *request,
              serf_bucket_t *response,
              int status_code,
@@ -725,7 +725,7 @@ cancel_fetch(serf_request_t *request,
     }
 
   /* We have no idea what went wrong. */
-  SVN_ERR_MALFUNCTION_NO_RETURN();
+  SVN_ERR_MALFUNCTION();
 }
 
 static svn_error_t *

Modified: subversion/trunk/subversion/libsvn_ra_serf/util.c
URL: 
http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_serf/util.c?rev=982512&r1=982511&r2=982512&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_ra_serf/util.c (original)
+++ subversion/trunk/subversion/libsvn_ra_serf/util.c Thu Aug  5 09:21:20 2010
@@ -1290,18 +1290,20 @@ svn_ra_serf__credentials_callback(char *
   return APR_SUCCESS;
 }
 
-/* Implements the serf_response_handler_t interface.  Wait for HTTP
-   response status and headers, and invoke CTX->response_handler() to
-   carry out operation-specific processing.  Afterwards, check for
-   connection close.
+/* Wait for HTTP response status and headers, and invoke CTX->
+   response_handler() to carry out operation-specific processing.
+   Afterwards, check for connection close.
+
+   SERF_STATUS allows returning errors to serf without creating a
+   subversion error object.
    */
-static apr_status_t
+static svn_error_t *
 handle_response(serf_request_t *request,
                 serf_bucket_t *response,
-                void *baton,
+                svn_ra_serf__handler_t *ctx,
+                apr_status_t *serf_status,
                 apr_pool_t *pool)
 {
-  svn_ra_serf__handler_t *ctx = baton;
   serf_status_line sl;
   apr_status_t status;
 
@@ -1309,14 +1311,8 @@ handle_response(serf_request_t *request,
     {
       /* Uh-oh.  Our connection died.  Requeue. */
       if (ctx->response_error)
-        {
-          status = ctx->response_error(request, response, 0,
-                                       ctx->response_error_baton);
-          if (status)
-            {
-              goto cleanup;
-            }
-        }
+        SVN_ERR(ctx->response_error(request, response, 0,
+                                    ctx->response_error_baton));
 
       svn_ra_serf__request_create(ctx);
 
@@ -1326,12 +1322,14 @@ handle_response(serf_request_t *request,
   status = serf_bucket_response_status(response, &sl);
   if (SERF_BUCKET_READ_ERROR(status))
     {
-      return status;
+      *serf_status = status;
+      return SVN_NO_ERROR; /* Handled by serf */
     }
   if (!sl.version && (APR_STATUS_IS_EOF(status) ||
                       APR_STATUS_IS_EAGAIN(status)))
     {
-      goto cleanup;
+      *serf_status = status;
+      return SVN_NO_ERROR; /* Handled by serf */
     }
 
   status = serf_bucket_response_wait_for_headers(response);
@@ -1339,7 +1337,8 @@ handle_response(serf_request_t *request,
     {
       if (!APR_STATUS_IS_EOF(status))
         {
-          goto cleanup;
+          *serf_status = status;
+          return SVN_NO_ERROR;
         }
 
       /* Cases where a lack of a response body (via EOF) is okay:
@@ -1352,7 +1351,7 @@ handle_response(serf_request_t *request,
        */
       if (strcmp(ctx->method, "HEAD") != 0 && sl.code != 204 && sl.code != 304)
         {
-          ctx->session->pending_error =
+          svn_error_t *err =
               svn_error_createf(SVN_ERR_RA_DAV_MALFORMED_DATA,
                                 svn_error_compose_create(
                                            ctx->session->pending_error,
@@ -1362,16 +1361,14 @@ handle_response(serf_request_t *request,
           /* This discard may be no-op, but let's preserve the algorithm
              used elsewhere in this function for clarity's sake. */
           svn_ra_serf__response_discard_handler(request, response, NULL, pool);
-          status = ctx->session->pending_error->apr_err;
-          goto cleanup;
+          return err;
         }
     }
 
   if (ctx->conn->last_status_code == 401 && sl.code < 400)
     {
-      svn_error_clear(
-           svn_auth_save_credentials(ctx->session->auth_state,
-                                     ctx->session->pool));
+      SVN_ERR(svn_auth_save_credentials(ctx->session->auth_state,
+                                        ctx->session->pool));
       ctx->session->auth_attempts = 0;
       ctx->session->auth_state = NULL;
       ctx->session->realm = NULL;
@@ -1382,49 +1379,38 @@ handle_response(serf_request_t *request,
   if (sl.code == 401 || sl.code == 407)
     {
       /* 401 Authorization or 407 Proxy-Authentication required */
-      svn_error_t *err;
       status = svn_ra_serf__response_discard_handler(request, response, NULL, 
pool);
 
       /* Don't bother handling the authentication request if the response
          wasn't received completely yet. Serf will call handle_response
          again when more data is received. */
-      if (! APR_STATUS_IS_EAGAIN(status))
-        {
-          err = svn_ra_serf__handle_auth(sl.code, ctx,
-                                         request, response, pool);
-          if (err)
-            {
-              ctx->session->pending_error = svn_error_compose_create(
-                                                  err,
-                                                  ctx->session->pending_error);
-              status = ctx->session->pending_error->apr_err;
-              goto cleanup;
-            }
-
-          svn_ra_serf__priority_request_create(ctx);
-          return status;
-        }
-      else
+      if (APR_STATUS_IS_EAGAIN(status))
         {
-          return status;
+          *serf_status = status;
+          return SVN_NO_ERROR;
         }
+
+      SVN_ERR(svn_ra_serf__handle_auth(sl.code, ctx,
+                                       request, response, pool));
+
+      svn_ra_serf__priority_request_create(ctx);
+
+      return SVN_NO_ERROR;
     }
   else if (sl.code == 409 || sl.code >= 500)
     {
       /* 409 Conflict: can indicate a hook error.
          5xx (Internal) Server error. */
-      ctx->session->pending_error = svn_error_compose_create(
-                 svn_ra_serf__handle_server_error(request, response, pool),
-                 ctx->session->pending_error);
+      SVN_ERR(svn_ra_serf__handle_server_error(request, response, pool));
 
       if (!ctx->session->pending_error)
         {
-          ctx->session->pending_error =
+          return
               svn_error_createf(APR_EGENERAL, NULL,
               _("Unspecified error message: %d %s"), sl.code, sl.reason);
         }
-      status = ctx->session->pending_error->apr_err;
-      goto cleanup;
+
+      return SVN_NO_ERROR; /* Error is set in caller */
     }
   else
     {
@@ -1446,46 +1432,65 @@ handle_response(serf_request_t *request,
             {
               svn_ra_serf__response_discard_handler(request, response, NULL,
                                                     pool);
-              ctx->session->pending_error = err;
-              status = ctx->session->pending_error->apr_err;
-              goto cleanup;
+              /* Ignore serf status code, just return the real error */
+
+              return svn_error_return(err);
             }
         }
 
       err = ctx->response_handler(request,response, ctx->response_baton, pool);
 
-      if (err)
+      if (err && !SERF_BUCKET_READ_ERROR(err->apr_err))
         {
-          status = err->apr_err;
-          if (!SERF_BUCKET_READ_ERROR(err->apr_err))
-            {
-              /* These errors are special cased in serf
-                 ### We hope no handler returns these by accident. */
-              svn_error_clear(err);
-            }
-          else
-            {
-              ctx->session->pending_error =
-                       svn_error_return(svn_error_compose_create(
-                                                       err,
-                                                       
ctx->session->pending_error));
-            }
+          /* These errors are special cased in serf
+             ### We hope no handler returns these by accident. */
+          *serf_status = err->apr_err;
+          svn_error_clear(err);
+          return SVN_NO_ERROR;
         }
+
+      return svn_error_return(err);
+    }
+}
+
+
+/* Implements serf_response_handler_t for handle_response. Storing
+   errors in ctx->session->pending_error if appropriate. */
+static apr_status_t
+handle_response_cb(serf_request_t *request,
+                   serf_bucket_t *response,
+                   void *baton,
+                   apr_pool_t *pool)
+{
+  svn_ra_serf__handler_t *ctx = baton;
+  svn_error_t *err;
+  apr_status_t serf_status = APR_SUCCESS;
+
+  err = handle_response(request, response, ctx, &serf_status, pool);
+
+  if (err)
+    {
+      ctx->session->pending_error =
+          svn_error_compose_create(ctx->session->pending_error, err);
+
+      serf_status = err->apr_err;
     }
 
-cleanup:
+  if (serf_status != APR_SUCCESS)
+    return serf_status;
+  else if (ctx->session->pending_error)
+    ctx->session->pending_error->apr_err;
 
-  return status;
+  return APR_SUCCESS;
 }
 
-/* svn_error_t * returning wrapper for setup_request.  If the CTX->setup()
-   callback is non-NULL, invoke it to carry out the majority of the
-   serf_request_setup_t implementation.  Otherwise, perform default
-   setup, with special handling for HEAD requests, and finer-grained
+/* If the CTX->setup() callback is non-NULL, invoke it to carry out the
+   majority of the serf_request_setup_t implementation.  Otherwise, perform
+   default setup, with special handling for HEAD requests, and finer-grained
    callbacks invoked (if non-NULL) to produce the request headers and
    body. */
 static svn_error_t *
-setup_request_cb(serf_request_t *request,
+setup_request(serf_request_t *request,
                  svn_ra_serf__handler_t *ctx,
                  serf_bucket_t **req_bkt,
                  serf_response_acceptor_t *acceptor,
@@ -1543,7 +1548,7 @@ setup_request_cb(serf_request_t *request
         }
     }
 
-  *handler = handle_response;
+  *handler = handle_response_cb;
   *handler_baton = ctx;
 
   return APR_SUCCESS;
@@ -1553,7 +1558,7 @@ setup_request_cb(serf_request_t *request
    request and its response handler callback). Handles errors for
    setup_request_cb */
 static apr_status_t
-setup_request(serf_request_t *request,
+setup_request_cb(serf_request_t *request,
               void *setup_baton,
               serf_bucket_t **req_bkt,
               serf_response_acceptor_t *acceptor,
@@ -1565,11 +1570,11 @@ setup_request(serf_request_t *request,
   svn_ra_serf__handler_t *ctx = setup_baton;
   svn_error_t *err;
 
-  err = setup_request_cb(request, ctx,
-                         req_bkt,
-                         acceptor, acceptor_baton,
-                         handler, handler_baton,
-                         pool);
+  err = setup_request(request, ctx,
+                      req_bkt,
+                      acceptor, acceptor_baton,
+                      handler, handler_baton,
+                      pool);
 
   if (err)
     {
@@ -1587,14 +1592,14 @@ serf_request_t *
 svn_ra_serf__request_create(svn_ra_serf__handler_t *handler)
 {
   return serf_connection_request_create(handler->conn->conn,
-                                        setup_request, handler);
+                                        setup_request_cb, handler);
 }
 
 serf_request_t *
 svn_ra_serf__priority_request_create(svn_ra_serf__handler_t *handler)
 {
   return serf_connection_priority_request_create(handler->conn->conn,
-                                                 setup_request, handler);
+                                                 setup_request_cb, handler);
 }
 
 svn_error_t *


Reply via email to