From f4c6404f50b8a2da601f97bfcd86ab744589b28e Mon Sep 17 00:00:00 2001 From: Albert Mojir Date: Mon, 20 Jun 2011 16:14:13 +0200 Subject: [PATCH] Bluetooth event loop dispatches dbus data on wakeup On some occasions when the event loop thread and a binder thread are both waiting for a message from dbus, both threads are not woken up when a message is received. This causes applications not receiving responses or events. This happens because both threads are listening to same socket and both threads are not guaranteed to wake up when there is data to read. To fix this we subscribe to callback to wake the eventloop when an message is added to incoming queue. To reproduce the issue: 1. Activate BT 2. Make phone Discoverable 3. Clock is ticking down from 120s 4. At 20s tap the setting again 5. Crash due to keyDispatchingTimedOut 6. Not possible to scan for other devices or making your phone discoverable again 7. Restart necessary Tell tale sign: 07-25 16:37:12.240 E/ActivityManager( 262): ANR in com.android.settings (com.android.settings/.bluetooth.BluetoothSettings) 07-25 16:37:12.240 E/ActivityManager( 262): Reason: keyDispatchingTimedOut Test case to verify this patch: android.bluetooth.BluetoothStressTest#testDiscoverable Change-Id: I7696b5722805e85cd0204ce2597e91594cbe6789 --- core/jni/android_server_BluetoothEventLoop.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/core/jni/android_server_BluetoothEventLoop.cpp b/core/jni/android_server_BluetoothEventLoop.cpp index 73dfdbe1d8e9f..ed2233b9b05b6 100644 --- a/core/jni/android_server_BluetoothEventLoop.cpp +++ b/core/jni/android_server_BluetoothEventLoop.cpp @@ -428,6 +428,7 @@ static void tearDownEventLoop(native_data_t *nat) { #define EVENT_LOOP_EXIT 1 #define EVENT_LOOP_ADD 2 #define EVENT_LOOP_REMOVE 3 +#define EVENT_LOOP_WAKEUP 4 dbus_bool_t dbusAddWatch(DBusWatch *watch, void *data) { native_data_t *nat = (native_data_t *)data; @@ -472,6 +473,13 @@ void dbusToggleWatch(DBusWatch *watch, void *data) { } } +void dbusWakeup(void *data) { + native_data_t *nat = (native_data_t *)data; + + char control = EVENT_LOOP_WAKEUP; + write(nat->controlFdW, &control, sizeof(char)); +} + static void handleWatchAdd(native_data_t *nat) { DBusWatch *watch; int newFD; @@ -555,6 +563,7 @@ static void *eventLoopMain(void *ptr) { dbus_connection_set_watch_functions(nat->conn, dbusAddWatch, dbusRemoveWatch, dbusToggleWatch, ptr, NULL); + dbus_connection_set_wakeup_main_function(nat->conn, dbusWakeup, ptr, NULL); nat->running = true; @@ -590,6 +599,11 @@ static void *eventLoopMain(void *ptr) { handleWatchRemove(nat); break; } + case EVENT_LOOP_WAKEUP: + { + // noop + break; + } } } } else {