From efc6433dd3c45a16b3767005c262b34c91dc6e00 Mon Sep 17 00:00:00 2001 From: Ben Tian Date: Tue, 3 Jun 2014 11:43:40 +0800 Subject: [PATCH] Bug 1019372 - Patch 4/6: [bluetooth2] Dispatch part of RemoteDevicePropertiesCallback to main thread, r=echou --- .../bluedroid/BluetoothServiceBluedroid.cpp | 99 +++++++++++-------- 1 file changed, 59 insertions(+), 40 deletions(-) diff --git a/dom/bluetooth2/bluedroid/BluetoothServiceBluedroid.cpp b/dom/bluetooth2/bluedroid/BluetoothServiceBluedroid.cpp index 3ff6be8b85ef..3a69bfebdba6 100644 --- a/dom/bluetooth2/bluedroid/BluetoothServiceBluedroid.cpp +++ b/dom/bluetooth2/bluedroid/BluetoothServiceBluedroid.cpp @@ -50,17 +50,16 @@ USING_BLUETOOTH_NAMESPACE static nsString sAdapterBdAddress; static nsString sAdapterBdName; static InfallibleTArray sAdapterBondedAddressArray; -static InfallibleTArray sRemoteDevicesPack; static nsTArray > sBondingRunnableArray; static nsTArray > sChangeDiscoveryRunnableArray; -static nsTArray > sGetDeviceRunnableArray; static nsTArray > sUnbondingRunnableArray; -static nsTArray sRequestedDeviceCountArray; // Static variables below should only be used on *main thread* static const bt_interface_t* sBtInterface; static nsTArray > sControllerArray; static nsTArray > sSetPropertyRunnableArray; +static nsTArray > sGetDeviceRunnableArray; +static nsTArray sRequestedDeviceCountArray; // Static variables below should only be used on *callback thread* @@ -412,6 +411,60 @@ AdapterPropertiesCallback(bt_status_t aStatus, int aNumProperties, NS_DispatchToMainThread(new AdapterPropertiesCallbackTask()); } +class RemoteDevicePropertiesCallbackTask : public nsRunnable +{ + const InfallibleTArray mProps; + nsString mRemoteDeviceBdAddress; +public: + RemoteDevicePropertiesCallbackTask( + const InfallibleTArray& aProps, + const nsAString& aRemoteDeviceBdAddress) + : mProps(aProps) + , mRemoteDeviceBdAddress(aRemoteDeviceBdAddress) + { } + + NS_IMETHOD + Run() + { + MOZ_ASSERT(NS_IsMainThread()); + + if (sRequestedDeviceCountArray.IsEmpty()) { + // This is possible because the callback would be called after turning + // Bluetooth on. + return NS_OK; + } + + // Update to registered BluetoothDevice objects + BluetoothSignal signal(NS_LITERAL_STRING("PropertyChanged"), + mRemoteDeviceBdAddress, mProps); + nsRefPtr + t = new DistributeBluetoothSignalTask(signal); + if (NS_FAILED(NS_DispatchToMainThread(t))) { + BT_WARNING("Failed to dispatch to main thread!"); + return NS_OK; + } + + static InfallibleTArray sRemoteDevicesPack; + + // Use address as the index + sRemoteDevicesPack.AppendElement( + BluetoothNamedValue(mRemoteDeviceBdAddress, mProps)); + + if (--sRequestedDeviceCountArray[0] == 0) { + if (!sGetDeviceRunnableArray.IsEmpty()) { + DispatchBluetoothReply(sGetDeviceRunnableArray[0], + sRemoteDevicesPack, EmptyString()); + sGetDeviceRunnableArray.RemoveElementAt(0); + } + + sRequestedDeviceCountArray.RemoveElementAt(0); + sRemoteDevicesPack.Clear(); + } + + return NS_OK; + } +}; + /** * RemoteDevicePropertiesCallback will be called, as the following conditions: * 1. When BT is turning on, bluedroid automatically execute this callback @@ -423,13 +476,6 @@ RemoteDevicePropertiesCallback(bt_status_t aStatus, bt_bdaddr_t *aBdAddress, { MOZ_ASSERT(!NS_IsMainThread()); - if (sRequestedDeviceCountArray.IsEmpty()) { - MOZ_ASSERT(sGetDeviceRunnableArray.IsEmpty()); - return; - } - - sRequestedDeviceCountArray[0]--; - InfallibleTArray props; nsString remoteDeviceBdAddress; @@ -454,36 +500,9 @@ RemoteDevicePropertiesCallback(bt_status_t aStatus, bt_bdaddr_t *aBdAddress, } } - // Update to registered BluetoothDevice objects - BluetoothSignal signal(NS_LITERAL_STRING("PropertyChanged"), - remoteDeviceBdAddress, props); - nsRefPtr - t = new DistributeBluetoothSignalTask(signal); - if (NS_FAILED(NS_DispatchToMainThread(t))) { - BT_WARNING("Failed to dispatch to main thread!"); - } - - // Use address as the index - sRemoteDevicesPack.AppendElement( - BluetoothNamedValue(remoteDeviceBdAddress, props)); - - if (sRequestedDeviceCountArray[0] == 0) { - MOZ_ASSERT(!sGetDeviceRunnableArray.IsEmpty()); - - if (sGetDeviceRunnableArray.IsEmpty()) { - BT_LOGR("No runnable to return"); - return; - } - - DispatchBluetoothReply(sGetDeviceRunnableArray[0], - sRemoteDevicesPack, EmptyString()); - - // After firing it, clean up cache - sRemoteDevicesPack.Clear(); - - sRequestedDeviceCountArray.RemoveElementAt(0); - sGetDeviceRunnableArray.RemoveElementAt(0); - } + // Redirect to main thread to avoid racing problem + NS_DispatchToMainThread( + new RemoteDevicePropertiesCallbackTask(props, remoteDeviceBdAddress)); } static void