[libvirt] [PATCH 1/3] esx: Wrap libcurl multi handle

Matthias Bolte matthias.bolte at googlemail.com
Mon Jul 2 21:44:51 UTC 2012


---
 src/esx/esx_vi.c |  111 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/esx/esx_vi.h |   18 +++++++++
 2 files changed, 129 insertions(+), 0 deletions(-)

diff --git a/src/esx/esx_vi.c b/src/esx/esx_vi.c
index 5b5ab69..48718b6 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 78d3986..9560bd2 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);
@@ -188,6 +190,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
  */
 
-- 
1.7.4.1




More information about the libvir-list mailing list