On Thu, Jul 27, 2023 at 01:59:54PM +0200, Laszlo Ersek wrote:
> On 7/27/23 13:46, Richard W.M. Jones wrote:
> > Using the libcurl share interface we can share data between the
> > separate curl easy handles in the pool.  For more about this see:
> > 
> > https://curl.se/libcurl/c/CURLSHOPT_SHARE.html
> > https://gist.github.com/bagder/7eccf74f8b6d70b5abefeb7f288dba9b
> > https://everything.curl.dev/libcurl/sharing
> > ---
> >  plugins/curl/pool.c | 65 +++++++++++++++++++++++++++++++++++++++++++++
> >  1 file changed, 65 insertions(+)
> 
> Can you document the benefits of this change in the commit message?
> (Faster downloads / lower CPU demand / lower memory usage -- just guessing.)

I would do if I knew what they were :-/ There are a bunch of
complexities which I don't understand.  I'm going to ask a question on
the curl mailing list about this in a min.

Rich.

> Acked-by: Laszlo Ersek <ler...@redhat.com>
> 
> Thanks
> Laszlo
> 
> > 
> > diff --git a/plugins/curl/pool.c b/plugins/curl/pool.c
> > index 10f9011d7..e9f387c38 100644
> > --- a/plugins/curl/pool.c
> > +++ b/plugins/curl/pool.c
> > @@ -52,6 +52,7 @@
> >  
> >  #include <nbdkit-plugin.h>
> >  
> > +#include "array-size.h"
> >  #include "ascii-ctype.h"
> >  #include "ascii-string.h"
> >  #include "cleanup.h"
> > @@ -72,6 +73,18 @@ static int get_content_length_accept_range (struct 
> > curl_handle *ch);
> >  static bool try_fallback_GET_method (struct curl_handle *ch);
> >  static size_t header_cb (void *ptr, size_t size, size_t nmemb, void 
> > *opaque);
> >  static size_t error_cb (char *ptr, size_t size, size_t nmemb, void 
> > *opaque);
> > +static void lock_cb (CURL *handle, curl_lock_data data,
> > +                     curl_lock_access access, void *userptr);
> > +static void unlock_cb (CURL *handle, curl_lock_data data,
> > +                       void *userptr);
> > +
> > +/* These locks protect access to the curl share data.  See:
> > + * https://gist.github.com/bagder/7eccf74f8b6d70b5abefeb7f288dba9b
> > + */
> > +static pthread_rwlock_t sharelocks[CURL_LOCK_DATA_LAST];
> > +
> > +/* Curl share data. */
> > +static CURLSH *share;
> >  
> >  /* This lock protects access to the curl_handles vector below. */
> >  static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
> > @@ -93,6 +106,22 @@ static size_t in_use = 0, waiting = 0;
> >  void
> >  load_pool (void)
> >  {
> > +  size_t i;
> > +
> > +  for (i = 0; i < ARRAY_SIZE (sharelocks); ++i)
> > +    pthread_rwlock_init (&sharelocks[i], NULL);
> > +
> > +  share = curl_share_init ();
> > +  if (share == NULL) {
> > +    nbdkit_error ("curl_share_init: %m");
> > +    exit (EXIT_FAILURE);
> > +  }
> > +  curl_share_setopt (share, CURLSHOPT_LOCKFUNC, lock_cb);
> > +  curl_share_setopt (share, CURLSHOPT_UNLOCKFUNC, unlock_cb);
> > +  curl_share_setopt (share, CURLSHOPT_SHARE, CURL_LOCK_DATA_CONNECT);
> > +  curl_share_setopt (share, CURLSHOPT_SHARE, CURL_LOCK_DATA_COOKIE);
> > +  curl_share_setopt (share, CURLSHOPT_SHARE, CURL_LOCK_DATA_DNS);
> > +  curl_share_setopt (share, CURLSHOPT_SHARE, CURL_LOCK_DATA_SSL_SESSION);
> >  }
> >  
> >  /* Close and free all handles in the pool. */
> > @@ -108,6 +137,12 @@ unload_pool (void)
> >    for (i = 0; i < curl_handles.len; ++i)
> >      free_handle (curl_handles.ptr[i]);
> >    curl_handle_list_reset (&curl_handles);
> > +
> > +  /* Free share data. */
> > +  curl_share_cleanup (share);
> > +
> > +  for (i = 0; i < ARRAY_SIZE (sharelocks); ++i)
> > +    pthread_rwlock_destroy (&sharelocks[i]);
> >  }
> >  
> >  /* Get a handle from the pool.
> > @@ -230,6 +265,9 @@ allocate_handle (void)
> >      goto err;
> >    }
> >  
> > +  /* Share settings with other handles. */
> > +  curl_easy_setopt (ch->c, CURLOPT_SHARE, share);
> > +
> >    /* Various options we always set.
> >     *
> >     * NB: Both here and below constants must be explicitly long because
> > @@ -621,3 +659,30 @@ error_cb (char *ptr, size_t size, size_t nmemb, void 
> > *opaque)
> >    return 0; /* in older curl, any size < requested will also be an error */
> >  #endif
> >  }
> > +
> > +static void
> > +lock_cb (CURL *handle, curl_lock_data data, curl_lock_access access,
> > +         void *userptr)
> > +{
> > +  assert (data < ARRAY_SIZE (sharelocks));
> > +
> > +  switch (access) {
> > +  case CURL_LOCK_ACCESS_SHARED:
> > +    pthread_rwlock_rdlock (&sharelocks[data]);
> > +    break;
> > +  case CURL_LOCK_ACCESS_SINGLE:
> > +    pthread_rwlock_wrlock (&sharelocks[data]);
> > +    break;
> > +  default:
> > +    /* CURL_LOCK_ACCESS_NONE is never used in the current libcurl code. */
> > +    abort ();
> > +  }
> > +}
> > +
> > +static void
> > +unlock_cb (CURL *handle, curl_lock_data data, void *userptr)
> > +{
> > +  assert (data < ARRAY_SIZE (sharelocks));
> > +
> > +  pthread_rwlock_unlock (&sharelocks[data]);
> > +}

-- 
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
Read my programming and virtualization blog: http://rwmj.wordpress.com
libguestfs lets you edit virtual machines.  Supports shell scripting,
bindings from many languages.  http://libguestfs.org
_______________________________________________
Libguestfs mailing list
Libguestfs@redhat.com
https://listman.redhat.com/mailman/listinfo/libguestfs

Reply via email to