mirror of
				https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
				synced 2025-11-03 09:01:50 -05:00 
			
		
		
		
	bluetooth: fix race condition in BlueZ5 device disconnection
SW: Pulseaudio 8.0 / BlueZ 5.39 Symptoms: While disconnecting/reconnecting a paired bluetooth headset (LG HBS750) audio fails roughly on every other connection. On a failed connection "pactl list cards" shows the bluetooth device's card but "Active Profile: off". Issuing "pacmd set-card-profile X a2dp_sink" makes audio work immediately. I realized that when this happened, the previous disconnection did not remove the card, instead it was only configured for "Active Profile: off" but otherwise left in place. Upon looking at PA debug logs I saw that the transport for the a2dp_sink was first set into disconnected state and then into idle state. In "device_connection_changed_cb()" this causes the "pa_bluetooth_device_any_transport_connected()" return true and the module-bluez5-device is not unloaded. Further investigation shows that this is caused by a race of module-bluez5-device.c:thread_func() and MediaPoint1::ClearConfiguration(). When the FD in thread_func() is closed (POLLHUP) an BLUETOOTH_MESSAGE_STREAM_FD_HUP message is sent into the main thread. The handler of this message unconditionally sets the transport into IDLE state. This is a problem if it has already been set into DISCONNECTED state.
This commit is contained in:
		
							parent
							
								
									6c99c2a278
								
							
						
					
					
						commit
						6a786c9375
					
				
					 1 changed files with 2 additions and 1 deletions
				
			
		| 
						 | 
				
			
			@ -2142,6 +2142,7 @@ static int device_process_msg(pa_msgobject *obj, int code, void *data, int64_t o
 | 
			
		|||
            pa_assert_se(pa_card_set_profile(m->card, pa_hashmap_get(m->card->profiles, "off"), false) >= 0);
 | 
			
		||||
            break;
 | 
			
		||||
        case BLUETOOTH_MESSAGE_STREAM_FD_HUP:
 | 
			
		||||
            if (u->transport->state > PA_BLUETOOTH_TRANSPORT_STATE_IDLE)
 | 
			
		||||
                pa_bluetooth_transport_set_state(u->transport, PA_BLUETOOTH_TRANSPORT_STATE_IDLE);
 | 
			
		||||
            break;
 | 
			
		||||
    }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue