ptp2: another round of memory leak fixes of PTPCanonEOSEvent
See f4313fdb74
This commit is contained in:
@@ -4489,17 +4489,15 @@ camera_canon_eos_capture (Camera *camera, CameraCaptureType type, CameraFilePath
|
||||
case PTP_EOSEvent_ObjectTransfer:
|
||||
GP_LOG_D ("object transfer requested: handle 0x%x, name %s, size %lu",
|
||||
event.u.object.Handle, event.u.object.Filename, event.u.object.ObjectSize);
|
||||
oi = event.u.object;
|
||||
move(oi, event.u.object);
|
||||
break;
|
||||
case PTP_EOSEvent_ObjectRemoved:
|
||||
GP_LOG_D ("object removed: handle 0x%x", event.u.object.Handle);
|
||||
ptp_free_objectinfo(&event.u.object);
|
||||
ptp_remove_object_from_cache(params, event.u.object.Handle);
|
||||
gp_filesystem_reset (camera->fs);
|
||||
break;
|
||||
case PTP_EOSEvent_ObjectAdded: {
|
||||
GP_LOG_D ("object added: handle 0x%x, name %s", event.u.object.Handle, event.u.object.Filename);
|
||||
ptp_free_objectinfo(&event.u.object);
|
||||
/* just add it to the filesystem, and return in CameraPath */
|
||||
|
||||
/* We have some form of objectinfo in event.u.object already, but we let the
|
||||
@@ -4510,13 +4508,14 @@ camera_canon_eos_capture (Camera *camera, CameraCaptureType type, CameraFilePath
|
||||
if (event.u.object.ObjectFormat == PTP_OFC_Association)
|
||||
continue;
|
||||
gp_filesystem_append (camera->fs, path->folder, path->name, context);
|
||||
oi = event.u.object;
|
||||
move(oi, event.u.object);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
GP_LOG_D ("unhandled eos event '%s'", ptp_get_eos_event_name(params, event.type));
|
||||
break;
|
||||
}
|
||||
ptp_free_eos_event(&event);
|
||||
/* for RAW+JPG mode capture, we just return the first image for now, and let wait_for_event get the rest. */
|
||||
if (oi.Handle)
|
||||
break;
|
||||
@@ -6010,6 +6009,8 @@ camera_trigger_canon_eos_capture (Camera *camera, GPContext *context)
|
||||
|
||||
/* Discard all collected events before starting the next capture. */
|
||||
GP_LOG_D("discarding %d EOS events", params->eos_events.len);
|
||||
for_each (PTPCanonEOSEvent*, pevt, params->eos_events)
|
||||
ptp_free_eos_event (pevt);
|
||||
free_array (¶ms->eos_events);
|
||||
|
||||
if (params->eos_camerastatus == 1)
|
||||
@@ -6080,6 +6081,7 @@ camera_trigger_canon_eos_capture (Camera *camera, GPContext *context)
|
||||
ptp_free_devicepropdesc (&dpd);
|
||||
}
|
||||
}
|
||||
ptp_free_eos_event(&event);
|
||||
}
|
||||
/* We found focus information, so half way pressing has finished! */
|
||||
if (in_focus)
|
||||
@@ -6151,6 +6153,7 @@ camera_trigger_canon_eos_capture (Camera *camera, GPContext *context)
|
||||
}
|
||||
break;
|
||||
}
|
||||
ptp_free_eos_event(&event);
|
||||
}
|
||||
} while (!eos_m_focus_done && waiting_for_timeout (&back_off_wait, focus_start, 2*1000)); /* wait 2 seconds for focus */
|
||||
/* full release now (even if the press has failed) */
|
||||
@@ -6639,7 +6642,7 @@ camera_wait_for_event (Camera *camera, int timeout,
|
||||
case PTP_EOSEvent_ObjectTransfer:
|
||||
GP_LOG_D ("object transfer requested: handle 0x%x, name %s, size %lu",
|
||||
eos_event.u.object.Handle, eos_event.u.object.Filename, eos_event.u.object.ObjectSize);
|
||||
ptp_free_objectinfo(&eos_event.u.object);
|
||||
ptp_free_eos_event(&eos_event);
|
||||
|
||||
C_MEM (path = calloc(1, sizeof(CameraFilePath)));
|
||||
strcpy (path->folder,"/");
|
||||
@@ -6718,7 +6721,7 @@ camera_wait_for_event (Camera *camera, int timeout,
|
||||
return GP_OK;
|
||||
case PTP_EOSEvent_ObjectContentChanged: {
|
||||
GP_LOG_D ("object content changed: handle 0x%x", eos_event.u.object.Handle);
|
||||
ptp_free_objectinfo(&eos_event.u.object);
|
||||
ptp_free_eos_event(&eos_event);
|
||||
/* It might have gone away in the meantime */
|
||||
PTPObject *ob;
|
||||
if (PTP_RC_OK != ptp_object_want(params, eos_event.u.object.Handle, PTPOBJECT_OBJECTINFO_LOADED, &ob))
|
||||
@@ -6741,7 +6744,7 @@ camera_wait_for_event (Camera *camera, int timeout,
|
||||
case PTP_EOSEvent_ObjectAdded:
|
||||
case PTP_EOSEvent_ObjectInfoChanged: {
|
||||
GP_LOG_D ("object added: handle 0x%x, name %s", eos_event.u.object.Handle, eos_event.u.object.Filename);
|
||||
ptp_free_objectinfo(&eos_event.u.object);
|
||||
ptp_free_eos_event(&eos_event);
|
||||
PTPObject *ob;
|
||||
if ( (eos_event.type == PTP_EOSEvent_ObjectInfoChanged) &&
|
||||
(PTP_RC_OK != ptp_object_find (params, eos_event.u.object.Handle, &ob))
|
||||
@@ -6828,11 +6831,13 @@ camera_wait_for_event (Camera *camera, int timeout,
|
||||
GP_LOG_D ("object removed: handle 0x%x", eos_event.u.object.Handle);
|
||||
ptp_remove_object_from_cache(params, eos_event.u.object.Handle);
|
||||
gp_filesystem_reset (camera->fs);
|
||||
ptp_free_eos_event(&eos_event);
|
||||
*eventtype = GP_EVENT_UNKNOWN;
|
||||
*eventdata = aprintf("ObjectRemoved");
|
||||
return GP_OK;
|
||||
default:
|
||||
GP_LOG_D ("Unhandled EOS event 0x%04x", eos_event.type);
|
||||
ptp_free_eos_event(&eos_event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2044,6 +2044,28 @@ ptp_free_objectpropdesc(PTPObjectPropDesc* opd)
|
||||
}
|
||||
}
|
||||
|
||||
void ptp_free_eos_event(PTPCanonEOSEvent *eos_event)
|
||||
{
|
||||
/* TODO: this function only exists because of the heap allocated Filename and Keyword members of
|
||||
* of PTPObjectInfo. This function needs to be called on every ptp_get_one_eos_event() result.
|
||||
* There are still tons of potential memory leaks in all sorts of error paths. The only sane solution
|
||||
* to this is, to make the Filename property a statically sized string (and drop Keywords, which is
|
||||
* unused anyway).
|
||||
*/
|
||||
switch (eos_event->type)
|
||||
{
|
||||
case PTP_EOSEvent_ObjectAdded:
|
||||
case PTP_EOSEvent_ObjectContentChanged:
|
||||
case PTP_EOSEvent_ObjectInfoChanged:
|
||||
case PTP_EOSEvent_ObjectRemoved:
|
||||
case PTP_EOSEvent_ObjectTransfer:
|
||||
ptp_free_objectinfo(&eos_event->u.object);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* ptp_free_params:
|
||||
@@ -2069,6 +2091,9 @@ ptp_free_params (PTPParams *params)
|
||||
ptp_free_devicepropdesc (¶ms->canon_props[i]);
|
||||
}
|
||||
free (params->canon_props);
|
||||
|
||||
for_each (PTPCanonEOSEvent*, pevt, params->eos_events)
|
||||
ptp_free_eos_event (pevt);
|
||||
free_array (¶ms->eos_events);
|
||||
|
||||
for (i=0;i<params->dpd_cache_len;i++)
|
||||
|
||||
@@ -74,6 +74,11 @@ static inline uint32_t _post_inc(uint32_t* o, int n)
|
||||
|
||||
#define ARRAYSIZE(ARRAY) (sizeof(ARRAY) / sizeof(ARRAY[0]))
|
||||
|
||||
#define move(dst, src) do { \
|
||||
dst = src; \
|
||||
memset(&(src), 0, sizeof(src)); \
|
||||
} while(0)
|
||||
|
||||
/* The follow set of macros implements a generic array or list of TYPE.
|
||||
* This is basically a TYPE* pointer and a length integer. This structure
|
||||
* together with the typical use-cases repeats regularly throughout the
|
||||
@@ -4943,6 +4948,7 @@ void ptp_free_propvalue (uint16_t, PTPPropValue*);
|
||||
void ptp_free_deviceinfo (PTPDeviceInfo *);
|
||||
void ptp_free_objectinfo (PTPObjectInfo *oi);
|
||||
void ptp_free_object (PTPObject *oi);
|
||||
void ptp_free_eos_event (PTPCanonEOSEvent *);
|
||||
|
||||
const char *ptp_strerror (uint16_t ret, uint16_t vendor);
|
||||
void ptp_debug (PTPParams *params, const char *format, ...)
|
||||
|
||||
Reference in New Issue
Block a user