On Tue, Jul 3, 2012 at 3:17 PM, Matthias Bolte
<matthias.bolte(a)googlemail.com> wrote:
2012/7/3 Doug Goldstein <cardoe(a)gentoo.org>:
> On Mon, Jul 2, 2012 at 4:44 PM, Matthias Bolte
> <matthias.bolte(a)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).
--
Doug Goldstein