All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH BlueZ 1/2] core/service: Rename service_shutdown to service_remove
@ 2013-07-08 15:28 Luiz Augusto von Dentz
  2013-07-08 15:28 ` [PATCH BlueZ 2/2] core/device: Fix crash while freeing services list Luiz Augusto von Dentz
  2013-07-08 17:15 ` [PATCH BlueZ 1/2] core/service: Rename service_shutdown to service_remove Mikel Astiz
  0 siblings, 2 replies; 5+ messages in thread
From: Luiz Augusto von Dentz @ 2013-07-08 15:28 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

This rename service_shutdown to service_remove to make it more similar to
other internal APIs such as device_remove which only do object
cleanup/free and do not have any disconnect logic.
---
 src/device.c  | 3 +--
 src/service.c | 3 ++-
 src/service.h | 2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/src/device.c b/src/device.c
index edd377c..afb0cfc 100644
--- a/src/device.c
+++ b/src/device.c
@@ -967,9 +967,8 @@ static void remove_service(gpointer data)
 	struct btd_service *service = data;
 	struct btd_device *device = btd_service_get_device(service);
 
-	service_shutdown(service);
 	device->pending = g_slist_remove(device->pending, service);
-	btd_service_unref(service);
+	service_remove(service);
 }
 
 static gboolean do_disconnect(gpointer user_data)
diff --git a/src/service.c b/src/service.c
index 83e1c1a..52a8291 100644
--- a/src/service.c
+++ b/src/service.c
@@ -168,12 +168,13 @@ int service_probe(struct btd_service *service)
 	return err;
 }
 
-void service_shutdown(struct btd_service *service)
+void service_remove(struct btd_service *service)
 {
 	change_state(service, BTD_SERVICE_STATE_UNAVAILABLE, 0);
 	service->profile->device_remove(service);
 	service->device = NULL;
 	service->profile = NULL;
+	btd_service_unref(service);
 }
 
 int btd_service_connect(struct btd_service *service)
diff --git a/src/service.h b/src/service.h
index 6ee8f17..5230115 100644
--- a/src/service.h
+++ b/src/service.h
@@ -46,7 +46,7 @@ struct btd_service *service_create(struct btd_device *device,
 						struct btd_profile *profile);
 
 int service_probe(struct btd_service *service);
-void service_shutdown(struct btd_service *service);
+void service_remove(struct btd_service *service);
 
 /* Connection control API */
 int btd_service_connect(struct btd_service *service);
-- 
1.8.1.4


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* [PATCH BlueZ 2/2] core/device: Fix crash while freeing services list
  2013-07-08 15:28 [PATCH BlueZ 1/2] core/service: Rename service_shutdown to service_remove Luiz Augusto von Dentz
@ 2013-07-08 15:28 ` Luiz Augusto von Dentz
  2013-07-08 17:22   ` Mikel Astiz
  2013-07-08 17:15 ` [PATCH BlueZ 1/2] core/service: Rename service_shutdown to service_remove Mikel Astiz
  1 sibling, 1 reply; 5+ messages in thread
From: Luiz Augusto von Dentz @ 2013-07-08 15:28 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

btd_service do alter its state on service_remove which can cause
plugins to attempt to access services list which may have freed some
services already.

To fix this the code now updates the list in place so the services are
first removed from services list before calling service_remove.
---
 src/device.c | 20 +++++++++++---------
 1 file changed, 11 insertions(+), 9 deletions(-)

diff --git a/src/device.c b/src/device.c
index afb0cfc..5a1f9c1 100644
--- a/src/device.c
+++ b/src/device.c
@@ -993,8 +993,12 @@ int device_block(struct btd_device *device, gboolean update_only)
 	if (device->connected)
 		do_disconnect(device);
 
-	g_slist_free_full(device->services, remove_service);
-	device->services = NULL;
+	while (device->services != NULL) {
+		struct btd_service *service = device->services->data;
+
+		device->services = g_slist_remove(device->services, service);
+		service_remove(service);
+	}
 
 	if (!update_only)
 		err = btd_adapter_block_address(device->adapter,
@@ -2361,7 +2365,6 @@ static void device_remove_stored(struct btd_device *device)
 
 void device_remove(struct btd_device *device, gboolean remove_stored)
 {
-
 	DBG("Removing device %s", device->path);
 
 	if (device->bonding) {
@@ -2378,10 +2381,12 @@ void device_remove(struct btd_device *device, gboolean remove_stored)
 	if (device->browse)
 		browse_request_cancel(device->browse);
 
-	g_slist_foreach(device->services, dev_disconn_service, NULL);
+	while (device->services != NULL) {
+		struct btd_service *service = device->services->data;
 
-	g_slist_free(device->pending);
-	device->pending = NULL;
+		device->services = g_slist_remove(device->services, service);
+		service_remove(service);
+	}
 
 	if (device->connected)
 		do_disconnect(device);
@@ -2397,9 +2402,6 @@ void device_remove(struct btd_device *device, gboolean remove_stored)
 	if (remove_stored)
 		device_remove_stored(device);
 
-	g_slist_free_full(device->services, remove_service);
-	device->services = NULL;
-
 	btd_device_unref(device);
 }
 
-- 
1.8.1.4


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH BlueZ 1/2] core/service: Rename service_shutdown to service_remove
  2013-07-08 15:28 [PATCH BlueZ 1/2] core/service: Rename service_shutdown to service_remove Luiz Augusto von Dentz
  2013-07-08 15:28 ` [PATCH BlueZ 2/2] core/device: Fix crash while freeing services list Luiz Augusto von Dentz
@ 2013-07-08 17:15 ` Mikel Astiz
  1 sibling, 0 replies; 5+ messages in thread
From: Mikel Astiz @ 2013-07-08 17:15 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth

Hi Luiz,

On Mon, Jul 8, 2013 at 5:28 PM, Luiz Augusto von Dentz
<luiz.dentz@gmail.com> wrote:
> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
>
> This rename service_shutdown to service_remove to make it more similar to
> other internal APIs such as device_remove which only do object
> cleanup/free and do not have any disconnect logic.

I personally don't like hiding unrefs in such a way but it's indeed
more consistent with device_remove() so if this is the convention to
be adopted, ack from my side.

Note however that adapter_remove() doesn't automatically call
btd_adapter_unref() so in this case it would need to be updated too.

Cheers,
Mikel

> ---
>  src/device.c  | 3 +--
>  src/service.c | 3 ++-
>  src/service.h | 2 +-
>  3 files changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/src/device.c b/src/device.c
> index edd377c..afb0cfc 100644
> --- a/src/device.c
> +++ b/src/device.c
> @@ -967,9 +967,8 @@ static void remove_service(gpointer data)
>         struct btd_service *service = data;
>         struct btd_device *device = btd_service_get_device(service);
>
> -       service_shutdown(service);
>         device->pending = g_slist_remove(device->pending, service);
> -       btd_service_unref(service);
> +       service_remove(service);
>  }
>
>  static gboolean do_disconnect(gpointer user_data)
> diff --git a/src/service.c b/src/service.c
> index 83e1c1a..52a8291 100644
> --- a/src/service.c
> +++ b/src/service.c
> @@ -168,12 +168,13 @@ int service_probe(struct btd_service *service)
>         return err;
>  }
>
> -void service_shutdown(struct btd_service *service)
> +void service_remove(struct btd_service *service)
>  {
>         change_state(service, BTD_SERVICE_STATE_UNAVAILABLE, 0);
>         service->profile->device_remove(service);
>         service->device = NULL;
>         service->profile = NULL;
> +       btd_service_unref(service);
>  }
>
>  int btd_service_connect(struct btd_service *service)
> diff --git a/src/service.h b/src/service.h
> index 6ee8f17..5230115 100644
> --- a/src/service.h
> +++ b/src/service.h
> @@ -46,7 +46,7 @@ struct btd_service *service_create(struct btd_device *device,
>                                                 struct btd_profile *profile);
>
>  int service_probe(struct btd_service *service);
> -void service_shutdown(struct btd_service *service);
> +void service_remove(struct btd_service *service);
>
>  /* Connection control API */
>  int btd_service_connect(struct btd_service *service);
> --
> 1.8.1.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH BlueZ 2/2] core/device: Fix crash while freeing services list
  2013-07-08 15:28 ` [PATCH BlueZ 2/2] core/device: Fix crash while freeing services list Luiz Augusto von Dentz
@ 2013-07-08 17:22   ` Mikel Astiz
  0 siblings, 0 replies; 5+ messages in thread
From: Mikel Astiz @ 2013-07-08 17:22 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: linux-bluetooth

Hi Luiz,

On Mon, Jul 8, 2013 at 5:28 PM, Luiz Augusto von Dentz
<luiz.dentz@gmail.com> wrote:
> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
>
> btd_service do alter its state on service_remove which can cause
> plugins to attempt to access services list which may have freed some
> services already.
>
> To fix this the code now updates the list in place so the services are
> first removed from services list before calling service_remove.
> ---
>  src/device.c | 20 +++++++++++---------
>  1 file changed, 11 insertions(+), 9 deletions(-)
>
> diff --git a/src/device.c b/src/device.c
> index afb0cfc..5a1f9c1 100644
> --- a/src/device.c
> +++ b/src/device.c
> @@ -993,8 +993,12 @@ int device_block(struct btd_device *device, gboolean update_only)
>         if (device->connected)
>                 do_disconnect(device);
>
> -       g_slist_free_full(device->services, remove_service);
> -       device->services = NULL;
> +       while (device->services != NULL) {
> +               struct btd_service *service = device->services->data;
> +
> +               device->services = g_slist_remove(device->services, service);
> +               service_remove(service);
> +       }
>
>         if (!update_only)
>                 err = btd_adapter_block_address(device->adapter,
> @@ -2361,7 +2365,6 @@ static void device_remove_stored(struct btd_device *device)
>
>  void device_remove(struct btd_device *device, gboolean remove_stored)
>  {
> -
>         DBG("Removing device %s", device->path);
>
>         if (device->bonding) {
> @@ -2378,10 +2381,12 @@ void device_remove(struct btd_device *device, gboolean remove_stored)
>         if (device->browse)
>                 browse_request_cancel(device->browse);
>
> -       g_slist_foreach(device->services, dev_disconn_service, NULL);

Wouldn't it be better to split this change to a separate patch? I
believe it could be subject to backport or revert.

> +       while (device->services != NULL) {
> +               struct btd_service *service = device->services->data;
>
> -       g_slist_free(device->pending);
> -       device->pending = NULL;

Why are the two lines above removed?

> +               device->services = g_slist_remove(device->services, service);
> +               service_remove(service);
> +       }
>
>         if (device->connected)
>                 do_disconnect(device);
> @@ -2397,9 +2402,6 @@ void device_remove(struct btd_device *device, gboolean remove_stored)
>         if (remove_stored)
>                 device_remove_stored(device);
>
> -       g_slist_free_full(device->services, remove_service);
> -       device->services = NULL;
> -
>         btd_device_unref(device);
>  }
>
> --
> 1.8.1.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

Cheers,
Mikel

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH BlueZ 2/2] core/device: Fix crash while freeing services list
  2013-07-05 14:03 [PATCH BlueZ 1/2] core/service: Make sure service is disconnected before shutdown Luiz Augusto von Dentz
@ 2013-07-05 14:03 ` Luiz Augusto von Dentz
  0 siblings, 0 replies; 5+ messages in thread
From: Luiz Augusto von Dentz @ 2013-07-05 14:03 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

btd_service do alter its state on service_shutdown which can cause
plugins to attempt to access services list which may have freed some
services already.

To fix this the code now updates the list  in place so any service that
is gonna be shutdown is removed from the list so it no longer accessible
after freed.
---
 src/device.c | 21 ++++++++++++++-------
 1 file changed, 14 insertions(+), 7 deletions(-)

diff --git a/src/device.c b/src/device.c
index edd377c..300c358 100644
--- a/src/device.c
+++ b/src/device.c
@@ -994,8 +994,13 @@ int device_block(struct btd_device *device, gboolean update_only)
 	if (device->connected)
 		do_disconnect(device);
 
-	g_slist_free_full(device->services, remove_service);
-	device->services = NULL;
+	while (device->services != NULL) {
+		struct btd_service *service = device->services->data;
+
+		device->services = g_slist_remove(device->services, service);
+		service_shutdown(service);
+		btd_service_unref(service);
+	}
 
 	if (!update_only)
 		err = btd_adapter_block_address(device->adapter,
@@ -2362,7 +2367,6 @@ static void device_remove_stored(struct btd_device *device)
 
 void device_remove(struct btd_device *device, gboolean remove_stored)
 {
-
 	DBG("Removing device %s", device->path);
 
 	if (device->bonding) {
@@ -2379,7 +2383,13 @@ void device_remove(struct btd_device *device, gboolean remove_stored)
 	if (device->browse)
 		browse_request_cancel(device->browse);
 
-	g_slist_foreach(device->services, dev_disconn_service, NULL);
+	while (device->services != NULL) {
+		struct btd_service *service = device->services->data;
+
+		device->services = g_slist_remove(device->services, service);
+		service_shutdown(service);
+		btd_service_unref(service);
+	}
 
 	g_slist_free(device->pending);
 	device->pending = NULL;
@@ -2398,9 +2408,6 @@ void device_remove(struct btd_device *device, gboolean remove_stored)
 	if (remove_stored)
 		device_remove_stored(device);
 
-	g_slist_free_full(device->services, remove_service);
-	device->services = NULL;
-
 	btd_device_unref(device);
 }
 
-- 
1.8.1.4


^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2013-07-08 17:22 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-07-08 15:28 [PATCH BlueZ 1/2] core/service: Rename service_shutdown to service_remove Luiz Augusto von Dentz
2013-07-08 15:28 ` [PATCH BlueZ 2/2] core/device: Fix crash while freeing services list Luiz Augusto von Dentz
2013-07-08 17:22   ` Mikel Astiz
2013-07-08 17:15 ` [PATCH BlueZ 1/2] core/service: Rename service_shutdown to service_remove Mikel Astiz
  -- strict thread matches above, loose matches on Subject: below --
2013-07-05 14:03 [PATCH BlueZ 1/2] core/service: Make sure service is disconnected before shutdown Luiz Augusto von Dentz
2013-07-05 14:03 ` [PATCH BlueZ 2/2] core/device: Fix crash while freeing services list Luiz Augusto von Dentz

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.