[libvirt] [PATCH 1/3] esx: Wrap libcurl multi handle
Matthias Bolte
matthias.bolte at googlemail.com
Sun Jul 8 09:30:12 UTC 2012
2012/7/3 Doug Goldstein <cardoe at gentoo.org>:
> On Tue, Jul 3, 2012 at 3:17 PM, Matthias Bolte
> <matthias.bolte at googlemail.com> wrote:
>> 2012/7/3 Doug Goldstein <cardoe at gentoo.org>:
>>> On Mon, Jul 2, 2012 at 4:44 PM, Matthias Bolte
>>> <matthias.bolte at googlemail.com> wrote:
>>>> ---
>>>> src/esx/esx_vi.c | 111 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
>>>> src/esx/esx_vi.h | 18 +++++++++
>>>> 2 files changed, 129 insertions(+), 0 deletions(-)
>>
>>>> +/* 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);
>>>> + }
>>>
>>> Since its a double pointer maybe setting the passed in value to NULL
>>> to prevent a double free situations?
>>
>> Actually that's what already happens here but hidden inside the
>> ESX_VI__TEMPLATE__FREE macro. Expanded esxVI_MultiCURL_Free looks like
>> this
>>
>> void esxVI_MultiCURL_Free(esxVI_MultiCURL **multi)
>> {
>> esxVI_MultiCURL *item;
>>
>> if (multi == NULL || *multi == NULL) {
>> return;
>> }
>>
>> item = *multi;
>>
>> 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);
>> }
>>
>> VIR_FREE(*multi);
>> }
>>
>> As VIR_FREE sets its argument to NULL after freeing it a double free
>> is not possible here.
>>
>>>> +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);
>>>
>>> Maybe add your free code here when count is 0? That way you wouldn't
>>> have to contend with a potential memory leak case when the free is
>>> called when its still ref'd.
>>
>> count is not meant as a refcount here. It's sole purpose is to avoid
>> freeing a multi handle that still has easy handles attached to it.
>> Also calling free one count == 0 here would not allow a call sequence
>> such as add, remove, add, remove.
>>
>> --
>> Matthias Bolte
>> http://photron.blogspot.com
>
>
> Ok good. Just was double checking. Then ACK from me on this patch (its
> not affected by the multi-CONTENT issue mentioned in the other
> e-mail).
Thanks, I pushed this one.
--
Matthias Bolte
http://photron.blogspot.com
More information about the libvir-list
mailing list