diff --git a/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.cpp b/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.cpp index 1dff826cde02..a444cafca184 100644 --- a/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.cpp +++ b/dom/bluetooth/bluedroid/BluetoothServiceBluedroid.cpp @@ -46,9 +46,7 @@ using namespace mozilla; using namespace mozilla::ipc; USING_BLUETOOTH_NAMESPACE -/** - * Static variables - */ +// TODO: Non-thread safe variables static bluetooth_device_t* sBtDevice; static const bt_interface_t* sBtInterface; static bool sAdapterDiscoverable = false; @@ -60,10 +58,14 @@ static InfallibleTArray sRemoteDevicesPack; static nsTArray > sControllerArray; static nsTArray > sBondingRunnableArray; static nsTArray > sGetDeviceRunnableArray; -static nsTArray > sSetPropertyRunnableArray; static nsTArray > sUnbondingRunnableArray; static nsTArray sRequestedDeviceCountArray; +// Static variables below should only be used on *main thread* +static nsTArray > sSetPropertyRunnableArray; + +// Static variables below should only be used on *callback thread* + /** * Classes only used in this file */ @@ -305,6 +307,24 @@ AdapterStateChangeCallback(bt_state_t aStatus) } } +class AdapterPropertiesCallbackTask MOZ_FINAL : public nsRunnable +{ +public: + NS_IMETHOD + Run() + { + MOZ_ASSERT(NS_IsMainThread()); + + if (!sSetPropertyRunnableArray.IsEmpty()) { + DispatchBluetoothReply(sSetPropertyRunnableArray[0], + BluetoothValue(true), EmptyString()); + sSetPropertyRunnableArray.RemoveElementAt(0); + } + + return NS_OK; + } +}; + /** * AdapterPropertiesCallback will be called after enable() but before * AdapterStateChangeCallback is called. At that moment, both @@ -384,12 +404,8 @@ AdapterPropertiesCallback(bt_status_t aStatus, int aNumProperties, BT_WARNING("Failed to dispatch to main thread!"); } - // bluedroid BTU task was stored in the task queue, see GKI_send_msg - if (!sSetPropertyRunnableArray.IsEmpty()) { - DispatchBluetoothReply(sSetPropertyRunnableArray[0], BluetoothValue(true), - EmptyString()); - sSetPropertyRunnableArray.RemoveElementAt(0); - } + // Redirect to main thread to avoid racing problem + NS_DispatchToMainThread(new AdapterPropertiesCallbackTask()); } /**