Re: [PATCH] esx: Add a wrapper for shared CURL handles

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



2011/4/10 Matthias Bolte <matthias.bolte@xxxxxxxxxxxxxx>:
> To be used to share a CURL handle between multiple threads in the
> upcoming domain event support.
> ---
> Âsrc/esx/esx_vi.c | Â176 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
> Âsrc/esx/esx_vi.h | Â 19 ++++++
> Â2 files changed, 195 insertions(+), 0 deletions(-)
>
> diff --git a/src/esx/esx_vi.c b/src/esx/esx_vi.c
> index 2fd09cd..84ff2e2 100644
> --- a/src/esx/esx_vi.c
> +++ b/src/esx/esx_vi.c
> @@ -85,6 +85,16 @@ ESX_VI__TEMPLATE__ALLOC(CURL)
> Â/* esxVI_CURL_Free */
> ÂESX_VI__TEMPLATE__FREE(CURL,
> Â{
> + Â ÂesxVI_SharedCURL *shared = item->shared;
> +
> + Â Âif (shared != NULL) {
> + Â Â Â ÂesxVI_SharedCURL_Remove(shared, item);
> +
> + Â Â Â Âif (shared->count == 0) {
> + Â Â Â Â Â ÂesxVI_SharedCURL_Free(&shared);
> + Â Â Â Â}
> + Â Â}
> +
> Â Â if (item->handle != NULL) {
> Â Â Â Â curl_easy_cleanup(item->handle);
> Â Â }
> @@ -418,6 +428,172 @@ esxVI_CURL_Upload(esxVI_CURL *curl, const char *url, const char *content)
>
>
> Â/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
> + * SharedCURL
> + */
> +
> +static void
> +esxVI_SharedCURL_Lock(CURL *handle ATTRIBUTE_UNUSED, curl_lock_data data,
> + Â Â Â Â Â Â Â Â Â Â Âcurl_lock_access access_ ATTRIBUTE_UNUSED, void *userptr)
> +{
> + Â Âint i;
> + Â ÂesxVI_SharedCURL *shared = userptr;
> +
> + Â Âswitch (data) {
> + Â Â Âcase CURL_LOCK_DATA_SHARE:
> + Â Â Â Âi = 0;
> + Â Â Â Âbreak;
> +
> + Â Â Âcase CURL_LOCK_DATA_COOKIE:
> + Â Â Â Âi = 1;
> + Â Â Â Âbreak;
> +
> + Â Â Âcase CURL_LOCK_DATA_DNS:
> + Â Â Â Âi = 2;
> + Â Â Â Âbreak;
> +
> + Â Â Âdefault:
> + Â Â Â ÂVIR_ERROR(_("Trying to lock unknown SharedCURL lock %d"), (int)data);
> + Â Â Â Âreturn;
> + Â Â}
> +
> + Â ÂvirMutexLock(&shared->locks[i]);
> +}
> +
> +static void
> +esxVI_SharedCURL_Unlock(CURL *handle ATTRIBUTE_UNUSED, curl_lock_data data,
> + Â Â Â Â Â Â Â Â Â Â Â Âvoid *userptr)
> +{
> + Â Âint i;
> + Â ÂesxVI_SharedCURL *shared = userptr;
> +
> + Â Âswitch (data) {
> + Â Â Âcase CURL_LOCK_DATA_SHARE:
> + Â Â Â Âi = 0;
> + Â Â Â Âbreak;
> +
> + Â Â Âcase CURL_LOCK_DATA_COOKIE:
> + Â Â Â Âi = 1;
> + Â Â Â Âbreak;
> +
> + Â Â Âcase CURL_LOCK_DATA_DNS:
> + Â Â Â Âi = 2;
> + Â Â Â Âbreak;
> +
> + Â Â Âdefault:
> + Â Â Â ÂVIR_ERROR(_("Trying to unlock unknown SharedCURL lock %d"), (int)data);
> + Â Â Â Âreturn;
> + Â Â}
> +
> + Â ÂvirMutexUnlock(&shared->locks[i]);
> +}
> +
> +/* esxVI_SharedCURL_Alloc */
> +ESX_VI__TEMPLATE__ALLOC(SharedCURL)
> +
> +/* esxVI_SharedCURL_Free */
> +ESX_VI__TEMPLATE__FREE(SharedCURL,
> +{
> + Â Âint i;
> +
> + Â Âif (item->count > 0) {
> + Â Â Â Â/* Better leak than crash */
> + Â Â Â ÂVIR_ERROR0(_("Trying to free SharedCURL object that is still in use"));
> + Â Â Â Âreturn;
> + Â Â}
> +
> + Â Âif (item->handle != NULL) {
> + Â Â Â Âcurl_share_cleanup(item->handle);
> + Â Â}
> +
> + Â Âfor (i = 0; i < ARRAY_CARDINALITY(item->locks); ++i) {
> + Â Â Â ÂvirMutexDestroy(&item->locks[i]);
> + Â Â}
> +})
> +
> +int
> +esxVI_SharedCURL_Add(esxVI_SharedCURL *shared, esxVI_CURL *curl)
> +{
> + Â Âint i;
> +
> + Â Âif (curl->handle == NULL) {
> + Â Â Â ÂESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
> + Â Â Â Â Â Â Â Â Â Â _("Cannot share uninitialized CURL handle"));
> + Â Â Â Âreturn -1;
> + Â Â}
> +
> + Â Âif (curl->shared != NULL) {
> + Â Â Â ÂESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
> + Â Â Â Â Â Â Â Â Â Â _("Cannot share CURL handle that is already shared"));
> + Â Â Â Âreturn -1;
> + Â Â}
> +
> + Â Âif (shared->handle == NULL) {
> + Â Â Â Âshared->handle = curl_share_init();
> +
> + Â Â Â Âif (shared->handle == NULL) {
> + Â Â Â Â Â ÂESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
> + Â Â Â Â Â Â Â Â Â Â Â Â _("Could not initialize CURL (share)"));
> + Â Â Â Â Â Âreturn -1;
> + Â Â Â Â}
> +
> + Â Â Â Âcurl_share_setopt(shared->handle, CURLSHOPT_LOCKFUNC,
> + Â Â Â Â Â Â Â Â Â Â Â Â ÂesxVI_SharedCURL_Lock);
> + Â Â Â Âcurl_share_setopt(shared->handle, CURLSHOPT_UNLOCKFUNC,
> + Â Â Â Â Â Â Â Â Â Â Â Â ÂesxVI_SharedCURL_Unlock);
> + Â Â Â Âcurl_share_setopt(shared->handle, CURLSHOPT_USERDATA, shared);
> + Â Â Â Âcurl_share_setopt(shared->handle, CURLSHOPT_SHARE,
> + Â Â Â Â Â Â Â Â Â Â Â Â ÂCURL_LOCK_DATA_COOKIE);
> + Â Â Â Âcurl_share_setopt(shared->handle, CURLSHOPT_SHARE,
> + Â Â Â Â Â Â Â Â Â Â Â Â ÂCURL_LOCK_DATA_DNS);
> +
> + Â Â Â Âfor (i = 0; i < ARRAY_CARDINALITY(shared->locks); ++i) {
> + Â Â Â Â Â Âif (virMutexInit(&shared->locks[i]) < 0) {
> + Â Â Â Â Â Â Â ÂESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
> + Â Â Â Â Â Â Â Â Â Â Â Â Â Â _("Could not initialize a CURL (share) mutex"));
> + Â Â Â Â Â Â Â Âreturn -1;
> + Â Â Â Â Â Â}
> + Â Â Â Â}
> + Â Â}
> +
> + Â Âcurl_easy_setopt(curl->handle, CURLOPT_SHARE, shared->handle);
> +
> + Â Âcurl->shared = shared;
> + Â Â++shared->count;
> +
> + Â Âreturn 0;
> +}
> +
> +int
> +esxVI_SharedCURL_Remove(esxVI_SharedCURL *shared, esxVI_CURL *curl)
> +{
> + Â Âif (curl->handle == NULL) {
> + Â Â Â ÂESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
> + Â Â Â Â Â Â Â Â Â Â _("Cannot unshare uninitialized CURL handle"));
> + Â Â Â Âreturn -1;
> + Â Â}
> +
> + Â Âif (curl->shared == NULL) {
> + Â Â Â ÂESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s",
> + Â Â Â Â Â Â Â Â Â Â _("Cannot unshare CURL handle that is not shared"));
> + Â Â Â Âreturn -1;
> + Â Â}
> +
> + Â Âif (curl->shared != shared) {
> + Â Â Â ÂESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", _("CURL (share) mismatch"));
> + Â Â Â Âreturn -1;
> + Â Â}
> +
> + Â Âcurl_easy_setopt(curl->handle, CURLOPT_SHARE, NULL);
> +
> + Â Âcurl->shared = NULL;
> + Â Â--shared->count;
> +
> + Â Âreturn 0;
> +}
> +
> +
> +
> +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
> Â* Context
> Â*/
>
> diff --git a/src/esx/esx_vi.h b/src/esx/esx_vi.h
> index 57788ac..560b2a6 100644
> --- a/src/esx/esx_vi.h
> +++ b/src/esx/esx_vi.h
> @@ -83,6 +83,7 @@ typedef enum _esxVI_ProductVersion esxVI_ProductVersion;
> Âtypedef enum _esxVI_Occurrence esxVI_Occurrence;
> Âtypedef struct _esxVI_ParsedHostCpuIdInfo esxVI_ParsedHostCpuIdInfo;
> Âtypedef struct _esxVI_CURL esxVI_CURL;
> +typedef struct _esxVI_SharedCURL esxVI_SharedCURL;
> Âtypedef struct _esxVI_Context esxVI_Context;
> Âtypedef struct _esxVI_Response esxVI_Response;
> Âtypedef struct _esxVI_Enumeration esxVI_Enumeration;
> @@ -151,6 +152,7 @@ struct _esxVI_CURL {
> Â Â virMutex lock;
> Â Â struct curl_slist *headers;
> Â Â char error[CURL_ERROR_SIZE];
> + Â ÂesxVI_SharedCURL *shared;
> Â};
>
> Âint esxVI_CURL_Alloc(esxVI_CURL **curl);
> @@ -162,6 +164,23 @@ int esxVI_CURL_Upload(esxVI_CURL *curl, const char *url, const char *content);
>
>
> Â/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
> + * SharedCURL
> + */
> +
> +struct _esxVI_SharedCURL {
> + Â ÂCURLSH *handle;
> + Â ÂvirMutex locks[3]; /* share, cookie, dns */
> + Â Âsize_t count;
> +};
> +
> +int esxVI_SharedCURL_Alloc(esxVI_SharedCURL **shared);
> +void esxVI_SharedCURL_Free(esxVI_SharedCURL **shared);
> +int esxVI_SharedCURL_Add(esxVI_SharedCURL *shared, esxVI_CURL *curl);
> +int esxVI_SharedCURL_Remove(esxVI_SharedCURL *shared, esxVI_CURL *curl);
> +
> +
> +
> +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
> Â* Context
> Â*/
>
> --
> 1.7.0.4
>

Ping :)

Matthias

--
libvir-list mailing list
libvir-list@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/libvir-list



[Index of Archives]     [Virt Tools]     [Libvirt Users]     [Lib OS Info]     [Fedora Users]     [Fedora Desktop]     [Fedora SELinux]     [Big List of Linux Books]     [Yosemite News]     [KDE Users]     [Fedora Tools]