From 017edaf79a5829bd2308de84fc8ddf5a0c522498 Mon Sep 17 00:00:00 2001 From: Matthias Bolte Date: Mon, 2 Jul 2012 22:52:48 +0200 Subject: [PATCH] esx: Wrap libcurl multi handle --- src/esx/esx_vi.c | 111 +++++++++++++++++++++++++++++++++++++++++++++++ src/esx/esx_vi.h | 18 ++++++++ 2 files changed, 129 insertions(+) diff --git a/src/esx/esx_vi.c b/src/esx/esx_vi.c index 5b5ab696d0..48718b6a22 100644 --- a/src/esx/esx_vi.c +++ b/src/esx/esx_vi.c @@ -86,6 +86,7 @@ ESX_VI__TEMPLATE__ALLOC(CURL) ESX_VI__TEMPLATE__FREE(CURL, { esxVI_SharedCURL *shared = item->shared; + esxVI_MultiCURL *multi = item->multi; if (shared != NULL) { esxVI_SharedCURL_Remove(shared, item); @@ -95,6 +96,14 @@ ESX_VI__TEMPLATE__FREE(CURL, } } + if (multi != NULL) { + esxVI_MultiCURL_Remove(multi, item); + + if (multi->count == 0) { + esxVI_MultiCURL_Free(&multi); + } + } + if (item->handle != NULL) { curl_easy_cleanup(item->handle); } @@ -555,11 +564,15 @@ esxVI_SharedCURL_Add(esxVI_SharedCURL *shared, esxVI_CURL *curl) } } + virMutexLock(&curl->lock); + curl_easy_setopt(curl->handle, CURLOPT_SHARE, shared->handle); curl->shared = shared; ++shared->count; + virMutexUnlock(&curl->lock); + return 0; } @@ -583,11 +596,109 @@ esxVI_SharedCURL_Remove(esxVI_SharedCURL *shared, esxVI_CURL *curl) return -1; } + virMutexLock(&curl->lock); + curl_easy_setopt(curl->handle, CURLOPT_SHARE, NULL); curl->shared = NULL; --shared->count; + virMutexUnlock(&curl->lock); + + return 0; +} + + + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * MultiCURL + */ + +/* esxVI_MultiCURL_Alloc */ +ESX_VI__TEMPLATE__ALLOC(MultiCURL) + +/* esxVI_MultiCURL_Free */ +ESX_VI__TEMPLATE__FREE(MultiCURL, +{ + if (item->count > 0) { + /* Better leak than crash */ + VIR_ERROR(_("Trying to free MultiCURL object that is still in use")); + return; + } + + if (item->handle != NULL) { + curl_multi_cleanup(item->handle); + } +}) + +int +esxVI_MultiCURL_Add(esxVI_MultiCURL *multi, esxVI_CURL *curl) +{ + if (curl->handle == NULL) { + ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", + _("Cannot add uninitialized CURL handle to a multi handle")); + return -1; + } + + if (curl->multi != NULL) { + ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", + _("Cannot add CURL handle to a multi handle twice")); + return -1; + } + + if (multi->handle == NULL) { + multi->handle = curl_multi_init(); + + if (multi->handle == NULL) { + ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", + _("Could not initialize CURL (multi)")); + return -1; + } + } + + virMutexLock(&curl->lock); + + curl_multi_add_handle(multi->handle, curl->handle); + + curl->multi = multi; + ++multi->count; + + virMutexUnlock(&curl->lock); + + return 0; +} + +int +esxVI_MultiCURL_Remove(esxVI_MultiCURL *multi, esxVI_CURL *curl) +{ + if (curl->handle == NULL) { + ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", + _("Cannot remove uninitialized CURL handle from a " + "multi handle")); + return -1; + } + + if (curl->multi == NULL) { + ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", + _("Cannot remove CURL handle from a multi handle when it " + "wasn't added before")); + return -1; + } + + if (curl->multi != multi) { + ESX_VI_ERROR(VIR_ERR_INTERNAL_ERROR, "%s", _("CURL (multi) mismatch")); + return -1; + } + + virMutexLock(&curl->lock); + + curl_multi_remove_handle(multi->handle, curl->handle); + + curl->multi = NULL; + --multi->count; + + virMutexUnlock(&curl->lock); + return 0; } diff --git a/src/esx/esx_vi.h b/src/esx/esx_vi.h index 78d3986096..9560bd2cdc 100644 --- a/src/esx/esx_vi.h +++ b/src/esx/esx_vi.h @@ -85,6 +85,7 @@ 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_MultiCURL esxVI_MultiCURL; typedef struct _esxVI_Context esxVI_Context; typedef struct _esxVI_Response esxVI_Response; typedef struct _esxVI_Enumeration esxVI_Enumeration; @@ -160,6 +161,7 @@ struct _esxVI_CURL { struct curl_slist *headers; char error[CURL_ERROR_SIZE]; esxVI_SharedCURL *shared; + esxVI_MultiCURL *multi; }; int esxVI_CURL_Alloc(esxVI_CURL **curl); @@ -187,6 +189,22 @@ int esxVI_SharedCURL_Remove(esxVI_SharedCURL *shared, esxVI_CURL *curl); +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * MultiCURL + */ + +struct _esxVI_MultiCURL { + CURLM *handle; + size_t count; +}; + +int esxVI_MultiCURL_Alloc(esxVI_MultiCURL **multi); +void esxVI_MultiCURL_Free(esxVI_MultiCURL **multi); +int esxVI_MultiCURL_Add(esxVI_MultiCURL *multi, esxVI_CURL *curl); +int esxVI_MultiCURL_Remove(esxVI_MultiCURL *multi, esxVI_CURL *curl); + + + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Context */ -- GitLab