Add reference counter to hdp_application
diff --git a/health/hdp.c b/health/hdp.c
index e4e3cde..69ac5b5 100644
--- a/health/hdp.c
+++ b/health/hdp.c
@@ -92,6 +92,7 @@
{
dbus_message_unref(dc_data->msg);
dbus_connection_unref(dc_data->conn);
+ hdp_application_unref(dc_data->app);
g_free(dc_data);
}
@@ -282,21 +283,10 @@
g_free(device);
}
-static void free_application(struct hdp_application *app)
-{
- if (app->dbus_watcher)
- g_dbus_remove_watch(connection, app->dbus_watcher);
-
- g_free(app->oname);
- g_free(app->description);
- g_free(app->path);
- g_free(app);
-}
-
static void remove_application(struct hdp_application *app)
{
DBG("Application %s deleted", app->path);
- free_application(app);
+ hdp_application_unref(app);
g_slist_foreach(adapters, (GFunc) update_adapter, NULL);
}
@@ -334,20 +324,21 @@
name = dbus_message_get_sender(msg);
if (!name) {
- free_application(app);
+ hdp_application_unref(app);
return g_dbus_create_error(msg,
ERROR_INTERFACE ".HealthError",
"Can't get sender name");
}
if (!set_app_path(app)) {
- free_application(app);
+ hdp_application_unref(app);
return g_dbus_create_error(msg,
ERROR_INTERFACE ".HealthError",
"Can't get a valid id for the application");
}
app->oname = g_strdup(name);
+ app->conn = dbus_connection_ref(conn);
applications = g_slist_prepend(applications, app);
@@ -393,7 +384,7 @@
static void manager_path_unregister(gpointer data)
{
- g_slist_foreach(applications, (GFunc) free_application, NULL);
+ g_slist_foreach(applications, (GFunc) hdp_application_unref, NULL);
g_slist_free(applications);
applications = NULL;
@@ -708,6 +699,7 @@
if (hdp_chan->mdep == HDP_MDEP_ECHO)
free_echo_data(hdp_chan->edata);
+ hdp_application_unref(hdp_chan->app);
g_free(hdp_chan->path);
g_free(hdp_chan);
}
@@ -734,7 +726,7 @@
hdp_chann->dev = dev;
hdp_chann->mdl = mdl;
hdp_chann->mdlid = mdlid;
- hdp_chann->app = app;
+ hdp_chann->app = hdp_application_ref(app);
if (app)
hdp_chann->mdep = app->id;
@@ -1852,7 +1844,7 @@
data = g_new0(struct hdp_create_dc, 1);
data->dev = device;
data->config = config;
- data->app = app;
+ data->app = hdp_application_ref(app);
data->msg = dbus_message_ref(msg);
data->conn = dbus_connection_ref(conn);
data->cb = hdp_mdl_conn_cb;
diff --git a/health/hdp_types.h b/health/hdp_types.h
index edfeeac..a993723 100644
--- a/health/hdp_types.h
+++ b/health/hdp_types.h
@@ -73,6 +73,7 @@
};
struct hdp_application {
+ DBusConnection *conn; /* For dbus watcher */
char *path; /* The path of the application */
uint16_t data_type; /* Data type handled for this application */
gboolean data_type_set; /* Flag for dictionary parsing */
@@ -84,6 +85,7 @@
uint8_t id; /* The identification is also the mdepid */
char *oname; /* Name of the owner application */
int dbus_watcher; /* Watch for clients disconnection */
+ gint ref; /* Reference counter */
};
struct hdp_adapter {
diff --git a/health/hdp_util.c b/health/hdp_util.c
index fefb6d3..a766be4 100644
--- a/health/hdp_util.c
+++ b/health/hdp_util.c
@@ -40,6 +40,8 @@
#include <btio.h>
#include <mcap_lib.h>
+#include <log.h>
+
typedef gboolean (*parse_item_f)(DBusMessageIter *iter, gpointer user_data,
GError **err);
@@ -292,6 +294,7 @@
struct hdp_application *app;
app = g_new0(struct hdp_application, 1);
+ app->ref = 1;
if (!parse_dict(dict_parser, iter, err, app))
goto fail;
if (!app->data_type_set || !app->role_set) {
@@ -302,7 +305,7 @@
return app;
fail:
- g_free(app);
+ hdp_application_unref(app);
return NULL;
}
@@ -837,6 +840,7 @@
if (mdep_data->destroy)
mdep_data->destroy(mdep_data->data);
+ hdp_application_unref(mdep_data->app);
g_free(mdep_data);
}
@@ -853,7 +857,7 @@
adapter_get_address(device_get_adapter(device->dev), &src);
mdep_data = g_new0(struct get_mdep_data, 1);
- mdep_data->app = app;
+ mdep_data->app = hdp_application_ref(app);
mdep_data->func = func;
mdep_data->data = data;
mdep_data->destroy = destroy;
@@ -1160,3 +1164,41 @@
return TRUE;
}
+
+static void hdp_free_application(struct hdp_application *app)
+{
+ if (app->dbus_watcher)
+ g_dbus_remove_watch(app->conn, app->dbus_watcher);
+
+ if (app->conn)
+ dbus_connection_unref(app->conn);
+ g_free(app->oname);
+ g_free(app->description);
+ g_free(app->path);
+ g_free(app);
+}
+
+struct hdp_application *hdp_application_ref(struct hdp_application *app)
+{
+ if (!app)
+ return NULL;
+
+ app->ref++;
+
+ DBG("health_application_ref(%p): ref=%d", app, app->ref);
+ return app;
+}
+
+void hdp_application_unref(struct hdp_application *app)
+{
+ if (!app)
+ return;
+
+ app->ref --;
+
+ DBG("health_application_unref(%p): ref=%d", app, app->ref);
+ if (app->ref > 0)
+ return;
+
+ hdp_free_application(app);
+}
diff --git a/health/hdp_util.h b/health/hdp_util.h
index f16ef32..c943ce2 100644
--- a/health/hdp_util.h
+++ b/health/hdp_util.h
@@ -50,4 +50,7 @@
GDestroyNotify destroy,
GError **err);
+struct hdp_application *hdp_application_ref(struct hdp_application *app);
+void hdp_application_unref(struct hdp_application *app);
+
#endif /* __HDP_UTIL_H__ */