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