Diff between 9811b52bc49456d27b50770ef02a096308bd98e1 and 1e64bbc81d65d50bb14ebdb014d9b58e947a0219

Changed Files

File Additions Deletions Status
android/gatt.c +2 -2 modified
src/shared/gatt-db.c +24 -2 modified
src/shared/gatt-db.h +3 -1 modified
tools/btgatt-server.c +2 -2 modified
unit/test-gatt.c +1 -1 modified

Full Patch

diff --git a/android/gatt.c b/android/gatt.c
index b9b3c7b..7d1115e 100644
--- a/android/gatt.c
+++ b/android/gatt.c
@@ -7040,7 +7040,7 @@ failed:
 	queue_destroy(services_sdp, NULL);
 	services_sdp = NULL;
 
-	gatt_db_destroy(gatt_db);
+	gatt_db_unref(gatt_db);
 	gatt_db = NULL;
 
 	bt_crypto_unref(crypto);
@@ -7081,7 +7081,7 @@ void bt_gatt_unregister(void)
 	queue_destroy(listen_apps, NULL);
 	listen_apps = NULL;
 
-	gatt_db_destroy(gatt_db);
+	gatt_db_unref(gatt_db);
 	gatt_db = NULL;
 
 	g_io_channel_unref(le_io);
diff --git a/src/shared/gatt-db.c b/src/shared/gatt-db.c
index 754d45f..b10db4a 100644
--- a/src/shared/gatt-db.c
+++ b/src/shared/gatt-db.c
@@ -48,6 +48,7 @@ static const bt_uuid_t included_service_uuid = { .type = BT_UUID16,
 					.value.u16 = GATT_INCLUDE_UUID };
 
 struct gatt_db {
+	int ref_count;
 	uint16_t next_handle;
 	struct queue *services;
 };
@@ -143,6 +144,16 @@ failed:
 	return NULL;
 }
 
+struct gatt_db *gatt_db_ref(struct gatt_db *db)
+{
+	if (!db)
+		return NULL;
+
+	__sync_fetch_and_add(&db->ref_count, 1);
+
+	return db;
+}
+
 struct gatt_db *gatt_db_new(void)
 {
 	struct gatt_db *db;
@@ -159,7 +170,7 @@ struct gatt_db *gatt_db_new(void)
 
 	db->next_handle = 0x0001;
 
-	return db;
+	return gatt_db_ref(db);
 }
 
 static void gatt_db_service_destroy(void *data)
@@ -174,7 +185,7 @@ static void gatt_db_service_destroy(void *data)
 	free(service);
 }
 
-void gatt_db_destroy(struct gatt_db *db)
+static void gatt_db_destroy(struct gatt_db *db)
 {
 	if (!db)
 		return;
@@ -183,6 +194,17 @@ void gatt_db_destroy(struct gatt_db *db)
 	free(db);
 }
 
+void gatt_db_unref(struct gatt_db *db)
+{
+	if (!db)
+		return;
+
+	if (__sync_sub_and_fetch(&db->ref_count, 1))
+		return;
+
+	gatt_db_destroy(db);
+}
+
 static int uuid_to_le(const bt_uuid_t *uuid, uint8_t *dst)
 {
 	bt_uuid_t uuid128;
diff --git a/src/shared/gatt-db.h b/src/shared/gatt-db.h
index ea9f2dc..7018b14 100644
--- a/src/shared/gatt-db.h
+++ b/src/shared/gatt-db.h
@@ -25,7 +25,9 @@ struct gatt_db;
 struct gatt_db_attribute;
 
 struct gatt_db *gatt_db_new(void);
-void gatt_db_destroy(struct gatt_db *db);
+
+struct gatt_db *gatt_db_ref(struct gatt_db *db);
+void gatt_db_unref(struct gatt_db *db);
 
 struct gatt_db_attribute *gatt_db_add_service(struct gatt_db *db,
 						const bt_uuid_t *uuid,
diff --git a/tools/btgatt-server.c b/tools/btgatt-server.c
index c603b30..87b8067 100644
--- a/tools/btgatt-server.c
+++ b/tools/btgatt-server.c
@@ -605,7 +605,7 @@ static struct server *server_create(int fd, uint16_t mtu, bool hr_visible)
 	return server;
 
 fail:
-	gatt_db_destroy(server->db);
+	gatt_db_unref(server->db);
 	free(server->device_name);
 	bt_att_unref(att);
 	free(server);
@@ -617,7 +617,7 @@ static void server_destroy(struct server *server)
 {
 	timeout_remove(server->hr_timeout_id);
 	bt_gatt_server_unref(server->gatt);
-	gatt_db_destroy(server->db);
+	gatt_db_unref(server->db);
 }
 
 static void usage(void)
diff --git a/unit/test-gatt.c b/unit/test-gatt.c
index 703430c..03a66b9 100644
--- a/unit/test-gatt.c
+++ b/unit/test-gatt.c
@@ -562,7 +562,7 @@ static void destroy_context(struct context *context)
 
 	bt_gatt_client_unref(context->client);
 	bt_gatt_server_unref(context->server);
-	gatt_db_destroy(context->db);
+	gatt_db_unref(context->db);
 
 	if (context->att)
 		bt_att_unref(context->att);