mirror of git://git.sysmocom.de/ofono
atmodem: Add reference counting to cb_data
the cb_data can be used by creating the structure with cb_data_new, and then there are two possibilities: - use it in a single callback function, and destroy it with a call to g_free. Example: - calling function: struct cb_data *cbd = cb_data_new(cb, data); if (g_at_chat_send(chat, buf, NULL, at_cgatt_cb, cbd, g_free) > 0) return; g_free(cbd); - called function (here at_cgatt_cb): static void at_cgatt_cb(gboolean ok, GAtResult *result, gpointer user_data) { struct cb_data *cbd = user_data; ofono_gprs_cb_t cb = cbd->cb; struct ofono_error error; decode_at_error(&error, g_at_result_final_response(result)); cb(&error, cbd->data); } note the absence of explicit g_free(cbd); - pass it through a train of callback functions, adding a reference at each pass cb_data_ref, and removing it with cb_data_unref. the use of cb_data_ref would replace a new object creation, while the use of cb_data_unref the use of g_free. Example: - calling function: struct cb_data *cbd = cb_data_new(cb, data); // no cb_ref at the creation if (g_at_chat_send(chat, buf, NULL, at_lte_set_default_attach_info_cb, cbd, cb_data_unref) > 0) goto end; cb_data_unref(cbd); - called function 1 (at_lte_set_default_attach_info_cb): static void at_lte_set_default_attach_info_cb(gboolean ok, GAtResult *result, gpointer user_data) { struct cb_data *cbd = user_data; cbd = cb_data_ref(cbd); if (g_at_chat_send(chat, buf, NULL, at_cgatt_cb, cbd, cb_data_unref) > 0) return; cb_data_unref(cbd); } - called function 2 (at_cgatt_cb): like above. no call to g_free or cb_data_unref. The terminal function doesn't need to know about the reference scheme.
This commit is contained in:
parent
f20da0e7f9
commit
eed785a4d7
|
@ -104,6 +104,7 @@ char *at_util_get_cgdcont_command(guint cid, enum ofono_gprs_proto proto,
|
|||
const char *apn);
|
||||
|
||||
struct cb_data {
|
||||
gint ref_count;
|
||||
void *cb;
|
||||
void *data;
|
||||
void *user;
|
||||
|
@ -114,12 +115,29 @@ static inline struct cb_data *cb_data_new(void *cb, void *data)
|
|||
struct cb_data *ret;
|
||||
|
||||
ret = g_new0(struct cb_data, 1);
|
||||
ret->ref_count = 1;
|
||||
ret->cb = cb;
|
||||
ret->data = data;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline struct cb_data *cb_data_ref(struct cb_data *cbd)
|
||||
{
|
||||
cbd->ref_count++;
|
||||
return cbd;
|
||||
}
|
||||
|
||||
static inline void cb_data_unref(gpointer user_data)
|
||||
{
|
||||
struct cb_data *cbd = user_data;
|
||||
|
||||
if (--cbd->ref_count)
|
||||
return;
|
||||
|
||||
g_free(cbd);
|
||||
}
|
||||
|
||||
static inline int at_util_convert_signal_strength(int strength)
|
||||
{
|
||||
int result;
|
||||
|
|
Loading…
Reference in New Issue