sr_dev_clear(): Always free sdi->priv (devc).
Until now, clear_helper() callbacks for std_dev_clear_with_callback() were expected to g_free(devc), but not all of them did that. Have std_dev_clear_with_callback() unconditionally g_free(sdi->priv) (i.e., devc), regardless of whether a clear_helper() callback was provided or not. It was doing g_free(sdi->priv) when no callback was provided already anyway. This makes the individual drivers' clear_helper() implementations shorter and prevents errors such as missing g_free(devc) calls. This works, because all drivers either call std_dev_clear_with_callback() directly, or indirectly via std_dev_clear(). This also allows us to remove some no-longer needed dev_clear() and clear_helper() implementations that only did g_free(devc) in favor of std_dev_clear().
This commit is contained in:
parent
53279f13e4
commit
8bf18daabb
|
@ -193,7 +193,6 @@ static void clear_helper(void *priv)
|
||||||
while (g_hash_table_iter_next(&iter, NULL, &value))
|
while (g_hash_table_iter_next(&iter, NULL, &value))
|
||||||
g_free(value);
|
g_free(value);
|
||||||
g_hash_table_unref(devc->ch_ag);
|
g_hash_table_unref(devc->ch_ag);
|
||||||
g_free(devc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dev_clear(const struct sr_dev_driver *di)
|
static int dev_clear(const struct sr_dev_driver *di)
|
||||||
|
|
|
@ -283,19 +283,6 @@ static GSList *scan(struct sr_dev_driver *di, GSList *options)
|
||||||
return std_scan_complete(di, devices);
|
return std_scan_complete(di, devices);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void clear_helper(void *priv)
|
|
||||||
{
|
|
||||||
struct dev_context *devc;
|
|
||||||
|
|
||||||
devc = priv;
|
|
||||||
g_free(devc);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int dev_clear(const struct sr_dev_driver *di)
|
|
||||||
{
|
|
||||||
return std_dev_clear_with_callback(di, clear_helper);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int dev_open(struct sr_dev_inst *sdi)
|
static int dev_open(struct sr_dev_inst *sdi)
|
||||||
{
|
{
|
||||||
struct sr_dev_driver *di = sdi->driver;
|
struct sr_dev_driver *di = sdi->driver;
|
||||||
|
@ -637,7 +624,7 @@ static struct sr_dev_driver dreamsourcelab_dslogic_driver_info = {
|
||||||
.cleanup = std_cleanup,
|
.cleanup = std_cleanup,
|
||||||
.scan = scan,
|
.scan = scan,
|
||||||
.dev_list = std_dev_list,
|
.dev_list = std_dev_list,
|
||||||
.dev_clear = dev_clear,
|
.dev_clear = std_dev_clear,
|
||||||
.config_get = config_get,
|
.config_get = config_get,
|
||||||
.config_set = config_set,
|
.config_set = config_set,
|
||||||
.config_list = config_list,
|
.config_list = config_list,
|
||||||
|
|
|
@ -246,7 +246,6 @@ static void clear_helper(void *priv)
|
||||||
|
|
||||||
devc = priv;
|
devc = priv;
|
||||||
g_free(devc->data_buf);
|
g_free(devc->data_buf);
|
||||||
g_free(devc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dev_clear(const struct sr_dev_driver *di)
|
static int dev_clear(const struct sr_dev_driver *di)
|
||||||
|
|
|
@ -351,7 +351,6 @@ static void clear_helper(void *priv)
|
||||||
|
|
||||||
devc = priv;
|
devc = priv;
|
||||||
g_slist_free(devc->enabled_analog_channels);
|
g_slist_free(devc->enabled_analog_channels);
|
||||||
g_free(devc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dev_clear(const struct sr_dev_driver *di)
|
static int dev_clear(const struct sr_dev_driver *di)
|
||||||
|
|
|
@ -120,8 +120,6 @@ static void clear_helper(void *priv)
|
||||||
|
|
||||||
g_free(devc->analog_groups);
|
g_free(devc->analog_groups);
|
||||||
g_free(devc->digital_groups);
|
g_free(devc->digital_groups);
|
||||||
|
|
||||||
g_free(devc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dev_clear(const struct sr_dev_driver *di)
|
static int dev_clear(const struct sr_dev_driver *di)
|
||||||
|
|
|
@ -162,7 +162,6 @@ static void clear_helper(void *priv)
|
||||||
|
|
||||||
devc = priv;
|
devc = priv;
|
||||||
g_slist_free(devc->enabled_channels);
|
g_slist_free(devc->enabled_channels);
|
||||||
g_free(devc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dev_clear(const struct sr_dev_driver *di)
|
static int dev_clear(const struct sr_dev_driver *di)
|
||||||
|
|
|
@ -160,7 +160,6 @@ static void clear_helper(void *priv)
|
||||||
|
|
||||||
libusb_free_transfer(devc->xfer_in);
|
libusb_free_transfer(devc->xfer_in);
|
||||||
libusb_free_transfer(devc->xfer_out);
|
libusb_free_transfer(devc->xfer_out);
|
||||||
g_free(devc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dev_clear(const struct sr_dev_driver *di)
|
static int dev_clear(const struct sr_dev_driver *di)
|
||||||
|
|
|
@ -52,7 +52,6 @@ static void clear_helper(void *priv)
|
||||||
ftdi_free(devc->ftdic);
|
ftdi_free(devc->ftdic);
|
||||||
g_free(devc->compressed_buf);
|
g_free(devc->compressed_buf);
|
||||||
g_free(devc->sample_buf);
|
g_free(devc->sample_buf);
|
||||||
g_free(devc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dev_clear(const struct sr_dev_driver *di)
|
static int dev_clear(const struct sr_dev_driver *di)
|
||||||
|
|
|
@ -124,8 +124,6 @@ static void clear_helper(void *priv)
|
||||||
lecroy_xstream_state_free(devc->model_state);
|
lecroy_xstream_state_free(devc->model_state);
|
||||||
|
|
||||||
g_free(devc->analog_groups);
|
g_free(devc->analog_groups);
|
||||||
|
|
||||||
g_free(devc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dev_clear(const struct sr_dev_driver *di)
|
static int dev_clear(const struct sr_dev_driver *di)
|
||||||
|
|
|
@ -288,7 +288,6 @@ static void clear_helper(void *priv)
|
||||||
g_free(devc->trigger_source);
|
g_free(devc->trigger_source);
|
||||||
g_free(devc->trigger_slope);
|
g_free(devc->trigger_slope);
|
||||||
g_free(devc->analog_groups);
|
g_free(devc->analog_groups);
|
||||||
g_free(devc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dev_clear(const struct sr_dev_driver *di)
|
static int dev_clear(const struct sr_dev_driver *di)
|
||||||
|
|
|
@ -295,7 +295,6 @@ static void clear_helper(void *priv)
|
||||||
devc = priv;
|
devc = priv;
|
||||||
g_free(devc->channels);
|
g_free(devc->channels);
|
||||||
g_free(devc->channel_groups);
|
g_free(devc->channel_groups);
|
||||||
g_free(devc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dev_clear(const struct sr_dev_driver *di)
|
static int dev_clear(const struct sr_dev_driver *di)
|
||||||
|
|
|
@ -203,25 +203,6 @@ static GSList *scan(struct sr_dev_driver *di, GSList *options)
|
||||||
return std_scan_complete(di, devices);
|
return std_scan_complete(di, devices);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void clear_helper(void *priv)
|
|
||||||
{
|
|
||||||
struct dev_context *devc;
|
|
||||||
|
|
||||||
devc = priv;
|
|
||||||
|
|
||||||
if (devc->acquisition) {
|
|
||||||
sr_err("Cannot clear device context during acquisition!");
|
|
||||||
return; /* Leak and pray. */
|
|
||||||
}
|
|
||||||
|
|
||||||
g_free(devc);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int dev_clear(const struct sr_dev_driver *di)
|
|
||||||
{
|
|
||||||
return std_dev_clear_with_callback(di, clear_helper);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Drain any pending data from the USB transfer buffers on the device.
|
/* Drain any pending data from the USB transfer buffers on the device.
|
||||||
* This may be necessary e.g. after a crash or generally to clean up after
|
* This may be necessary e.g. after a crash or generally to clean up after
|
||||||
* an abnormal condition.
|
* an abnormal condition.
|
||||||
|
@ -750,7 +731,7 @@ static struct sr_dev_driver sysclk_lwla_driver_info = {
|
||||||
.cleanup = std_cleanup,
|
.cleanup = std_cleanup,
|
||||||
.scan = scan,
|
.scan = scan,
|
||||||
.dev_list = std_dev_list,
|
.dev_list = std_dev_list,
|
||||||
.dev_clear = dev_clear,
|
.dev_clear = std_dev_clear,
|
||||||
.config_get = config_get,
|
.config_get = config_get,
|
||||||
.config_set = config_set,
|
.config_set = config_set,
|
||||||
.config_channel_set = config_channel_set,
|
.config_channel_set = config_channel_set,
|
||||||
|
|
|
@ -131,7 +131,6 @@ static void clear_helper(void *priv)
|
||||||
|
|
||||||
g_free(devc->analog_groups);
|
g_free(devc->analog_groups);
|
||||||
g_free(devc->digital_groups);
|
g_free(devc->digital_groups);
|
||||||
g_free(devc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dev_clear(const struct sr_dev_driver *di)
|
static int dev_clear(const struct sr_dev_driver *di)
|
||||||
|
|
17
src/std.c
17
src/std.c
|
@ -333,16 +333,18 @@ SR_PRIV int std_serial_dev_acquisition_stop(struct sr_dev_inst *sdi)
|
||||||
* This function can be used to implement the dev_clear() driver API
|
* This function can be used to implement the dev_clear() driver API
|
||||||
* callback. dev_close() is called before every sr_dev_inst is cleared.
|
* callback. dev_close() is called before every sr_dev_inst is cleared.
|
||||||
*
|
*
|
||||||
* The only limitation is driver-specific device contexts (sdi->priv).
|
* The only limitation is driver-specific device contexts (sdi->priv / devc).
|
||||||
* These are freed, but any dynamic allocation within structs stored
|
* These are freed, but any dynamic allocation within structs stored
|
||||||
* there cannot be freed.
|
* there cannot be freed.
|
||||||
*
|
*
|
||||||
* @param[in] driver The driver which will have its instances released.
|
* @param[in] driver The driver which will have its instances released.
|
||||||
* Must not be NULL.
|
* Must not be NULL.
|
||||||
* @param[in] clear_private If not NULL, this points to a function called
|
* @param[in] clear_private If not NULL, this points to a function called
|
||||||
* with sdi->priv as argument. The function can then clear
|
* with sdi->priv (devc) as argument. The function can then clear
|
||||||
* any device instance-specific resources kept there.
|
* any device instance-specific resources kept there.
|
||||||
* It must also clear the struct pointed to by sdi->priv.
|
* It must NOT clear the struct pointed to by sdi->priv (devc),
|
||||||
|
* since this function will always free it after clear_private()
|
||||||
|
* has run.
|
||||||
*
|
*
|
||||||
* @retval SR_OK Success.
|
* @retval SR_OK Success.
|
||||||
* @retval SR_ERR_ARG Invalid argument.
|
* @retval SR_ERR_ARG Invalid argument.
|
||||||
|
@ -388,12 +390,13 @@ SR_PRIV int std_dev_clear_with_callback(const struct sr_dev_driver *driver,
|
||||||
if (sdi->inst_type == SR_INST_MODBUS)
|
if (sdi->inst_type == SR_INST_MODBUS)
|
||||||
sr_modbus_free(sdi->conn);
|
sr_modbus_free(sdi->conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Clear driver-specific stuff, if any. */
|
||||||
if (clear_private)
|
if (clear_private)
|
||||||
/* The helper function is responsible for freeing
|
|
||||||
* its own sdi->priv! */
|
|
||||||
clear_private(sdi->priv);
|
clear_private(sdi->priv);
|
||||||
else
|
|
||||||
g_free(sdi->priv);
|
/* Clear sdi->priv (devc). */
|
||||||
|
g_free(sdi->priv);
|
||||||
|
|
||||||
sr_dev_inst_free(sdi);
|
sr_dev_inst_free(sdi);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue