summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrédéric Danis <frederic.danis@linux.intel.com>2012-05-15 15:55:36 +0200
committerArun Raghavan <arun.raghavan@collabora.co.uk>2012-07-03 17:18:13 +0530
commit1c055d70b09fd63156cdc8a49989977031e0f4af (patch)
tree8a9ab4c87965507cc8cf2b9746fe5dbbfe794faf
parent3643966f676c5084574811ee5c61e6c3b1383575 (diff)
bluetooth: Fix crash on disconnection
When a Bluetooth headset is connected only to HFP profile (not connected to A2DP) and host streams to it, a crash occurs if host disconnects. When HFP disconnects, audio thread will fail on POLLHUP then generate a message to set PA profile to Off before ending. If this message is managed before PA unload bluetooth device module, all works fine. But, if this message is managed during module unload, this finish by re-entrance in release code (stop_thread) and a crash. This fix prevents to process profile change when module is unloading.
-rw-r--r--src/modules/bluetooth/module-bluetooth-device.c16
1 files changed, 9 insertions, 7 deletions
diff --git a/src/modules/bluetooth/module-bluetooth-device.c b/src/modules/bluetooth/module-bluetooth-device.c
index b7945ede..0b12cc7b 100644
--- a/src/modules/bluetooth/module-bluetooth-device.c
+++ b/src/modules/bluetooth/module-bluetooth-device.c
@@ -187,7 +187,7 @@ struct userdata {
};
enum {
- BLUETOOTH_MESSAGE_SET_PROFILE,
+ BLUETOOTH_MESSAGE_IO_THREAD_FAILED,
BLUETOOTH_MESSAGE_MAX
};
@@ -1135,12 +1135,14 @@ static int device_process_msg(pa_msgobject *obj, int code, void *data, int64_t o
struct bluetooth_msg *u = BLUETOOTH_MSG(obj);
switch (code) {
- case BLUETOOTH_MESSAGE_SET_PROFILE: {
- const char *profile = data;
- pa_log_debug("Switch profile to %s requested", profile);
+ case BLUETOOTH_MESSAGE_IO_THREAD_FAILED: {
+ if (u->card->module->unload_requested)
+ break;
+
+ pa_log_debug("Switching the profile to off due to IO thread failure.");
- if (pa_card_set_profile(u->card, profile, FALSE) < 0)
- pa_log_debug("Failed to switch profile to %s", profile);
+ if (pa_card_set_profile(u->card, "off", FALSE) < 0)
+ pa_log_debug("Failed to switch profile to off");
break;
}
}
@@ -1750,7 +1752,7 @@ static void thread_func(void *userdata) {
fail:
/* If this was no regular exit from the loop we have to continue processing messages until we receive PA_MESSAGE_SHUTDOWN */
pa_log_debug("IO thread failed");
- pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(u->msg), BLUETOOTH_MESSAGE_SET_PROFILE, "off", 0, NULL, NULL);
+ pa_asyncmsgq_post(pa_thread_mq_get()->outq, PA_MSGOBJECT(u->msg), BLUETOOTH_MESSAGE_IO_THREAD_FAILED, NULL, 0, NULL, NULL);
pa_asyncmsgq_wait_for(u->thread_mq.inq, PA_MESSAGE_SHUTDOWN);
finish: