You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by rh...@apache.org on 2010/03/16 14:34:36 UTC

svn commit: r923737 - in /subversion/trunk/subversion/libsvn_ra_neon: ra_neon.h session.c

Author: rhuijben
Date: Tue Mar 16 13:34:36 2010
New Revision: 923737

URL: http://svn.apache.org/viewvc?rev=923737&view=rev
Log:
Improve the progress information from libsvn_ra_neon, for the case where
no total is available, by combining the results to one grand total like
how the other RA-layers do this.

Client applications such as TortoiseSVN, Subclipse and AnkhSVN who handle
these progress callbacks, can't identify the two internal sessions inside
neon and therefore had a hard time guessing the number of bytes neon really
transfers; especially for short requests.

* subversion/libsvn_ra_neon/ra_neon.h
  (svn_ra_neon__session_t): Add total_progress variable and name the struct
    to provide better debug information.

* subversion/libsvn_ra_neon/session.c
  (neonprogress_baton_t): Add ra session and last_progress variables. Remove
    now unused progress handler.
  (ra_neon_neonprogress): Calculate total number of bytes over multiple
    sessions.
  (svn_ra_neon__open): Only hook progress callback if we need it. Use two
    separate batons for the separate neon sessions.

Modified:
    subversion/trunk/subversion/libsvn_ra_neon/ra_neon.h
    subversion/trunk/subversion/libsvn_ra_neon/session.c

Modified: subversion/trunk/subversion/libsvn_ra_neon/ra_neon.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_neon/ra_neon.h?rev=923737&r1=923736&r2=923737&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_ra_neon/ra_neon.h (original)
+++ subversion/trunk/subversion/libsvn_ra_neon/ra_neon.h Tue Mar 16 13:34:36 2010
@@ -82,7 +82,7 @@ typedef struct {
 
 
 
-typedef struct {
+typedef struct svn_ra_neon__session_t {
   apr_pool_t *pool;
   svn_stringbuf_t *url;                 /* original, unparsed session url */
   ne_uri root;                          /* parsed version of above */
@@ -113,6 +113,9 @@ typedef struct {
   svn_ra_progress_notify_func_t progress_func;
   void *progress_baton;
 
+  apr_off_t total_progress;             /* Total number of bytes sent in this
+                                           session with a -1 total marker */
+
   /* Maps SVN_RA_CAPABILITY_foo keys to "yes" or "no" values.
      If a capability is not yet discovered, it is absent from the table.
      The table itself is allocated in the svn_ra_neon__session_t's pool;

Modified: subversion/trunk/subversion/libsvn_ra_neon/session.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_ra_neon/session.c?rev=923737&r1=923736&r2=923737&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_ra_neon/session.c (original)
+++ subversion/trunk/subversion/libsvn_ra_neon/session.c Tue Mar 16 13:34:36 2010
@@ -680,8 +680,8 @@ ra_neon_get_schemes(apr_pool_t *pool)
 
 typedef struct neonprogress_baton_t
 {
-  svn_ra_progress_notify_func_t progress_func;
-  void *progress_baton;
+  svn_ra_neon__session_t *ras;
+  apr_off_t last_progress;
   apr_pool_t *pool;
 } neonprogress_baton_t;
 
@@ -692,12 +692,36 @@ ra_neon_neonprogress(void *baton, ne_off
 ra_neon_neonprogress(void *baton, off_t progress, off_t total)
 #endif /* SVN_NEON_0_27 */
 {
-  const neonprogress_baton_t *neonprogress_baton = baton;
-  if (neonprogress_baton->progress_func)
+  neonprogress_baton_t *pb = baton;
+  svn_ra_neon__session_t *ras = pb->ras;
+
+ if (ras->progress_func)
     {
-      neonprogress_baton->progress_func(progress, total,
-                                        neonprogress_baton->progress_baton,
-                                        neonprogress_baton->pool);
+      if (total < 0)
+        {
+          /* Neon sends the total number of bytes sent for this specific
+             session and there are two sessions active at once.
+
+             For this case we combine the totals to allow clients to provide
+             a better progress indicator. */
+
+          if (progress >= pb->last_progress)
+            ras->total_progress += (progress - pb->last_progress);
+          else
+            /* Session total has been reset. A new stream started */
+            ras->total_progress += pb->last_progress;
+
+          pb->last_progress = progress;
+
+          ras->progress_func(ras->total_progress, -1, ras->progress_baton,
+                             pb->pool);
+        }
+      else
+        {
+          /* Neon provides total bytes to receive information. Pass literaly
+             to allow providing a percentage. */
+          ras->progress_func(progress, total, ras->progress_baton, pb->pool);
+        }
     }
 }
 
@@ -763,8 +787,6 @@ svn_ra_neon__open(svn_ra_session_t *sess
   const char *server_group;
   unsigned int neon_auth_types = 0;
   const char *pkcs11_provider;
-  neonprogress_baton_t *neonprogress_baton =
-    apr_pcalloc(pool, sizeof(*neonprogress_baton));
   const char *useragent = NULL;
   const char *client_string = NULL;
   svn_revnum_t ignored_revnum;
@@ -1032,11 +1054,22 @@ svn_ra_neon__open(svn_ra_session_t *sess
           ne_ssl_trust_default_ca(sess2);
         }
     }
-  neonprogress_baton->pool = pool;
-  neonprogress_baton->progress_baton = callbacks->progress_baton;
-  neonprogress_baton->progress_func = callbacks->progress_func;
-  ne_set_progress(sess, ra_neon_neonprogress, neonprogress_baton);
-  ne_set_progress(sess2, ra_neon_neonprogress, neonprogress_baton);
+
+  if (ras->progress_func)
+    {
+      neonprogress_baton_t *progress1 = apr_pcalloc(pool, sizeof(*progress1));
+      neonprogress_baton_t *progress2 = apr_pcalloc(pool, sizeof(*progress2));
+
+      progress1->pool = pool;
+      progress1->ras = ras;
+      progress1->last_progress = 0;
+
+      *progress2 = *progress1;
+
+      ne_set_progress(sess, ra_neon_neonprogress, progress1);
+      ne_set_progress(sess2, ra_neon_neonprogress, progress2);
+    }
+
   session->priv = ras;
 
   return svn_ra_neon__exchange_capabilities(ras, &ignored_revnum, pool);