From b8aa037602eff1fe5fbc9cce07a6f9bc34d19a3e Mon Sep 17 00:00:00 2001 From: Jaikumar Ganesh Date: Wed, 31 Mar 2010 11:23:49 -0700 Subject: Fix crash while turning bluetooth on, due to a race condition. Bug: 2561150 Race condition: We were basing whether the event loop is running or not on whether nat->pollData was null or not. In rare cases, eventLoopMain would have not started, isEventLoopRunning returns true; java side makes a dbus call and the watches get set to null, causing a crash in dbus_connection_set_watch_functions when eventLoopMain starts. Change-Id: I863f182185a8e956fd53cb58783b7fe0ecfb2ddb --- core/jni/android_bluetooth_common.h | 2 ++ core/jni/android_server_BluetoothEventLoop.cpp | 9 +++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) (limited to 'core') diff --git a/core/jni/android_bluetooth_common.h b/core/jni/android_bluetooth_common.h index ef9b66b..378bb6f 100644 --- a/core/jni/android_bluetooth_common.h +++ b/core/jni/android_bluetooth_common.h @@ -88,6 +88,8 @@ struct event_loop_native_data_t { int envVer; /* reference to our java self */ jobject me; + /* flag to indicate if the event loop thread is running */ + bool running; }; struct _Properties { diff --git a/core/jni/android_server_BluetoothEventLoop.cpp b/core/jni/android_server_BluetoothEventLoop.cpp index 0e7fd66..259cc01 100644 --- a/core/jni/android_server_BluetoothEventLoop.cpp +++ b/core/jni/android_server_BluetoothEventLoop.cpp @@ -548,6 +548,8 @@ static void *eventLoopMain(void *ptr) { dbus_connection_set_watch_functions(nat->conn, dbusAddWatch, dbusRemoveWatch, dbusToggleWatch, ptr, NULL); + nat->running = true; + while (1) { for (int i = 0; i < nat->pollMemberCount; i++) { if (!nat->pollData[i].revents) { @@ -591,7 +593,7 @@ static void *eventLoopMain(void *ptr) { break; } } - while (dbus_connection_dispatch(nat->conn) == + while (dbus_connection_dispatch(nat->conn) == DBUS_DISPATCH_DATA_REMAINS) { } @@ -607,6 +609,8 @@ static jboolean startEventLoopNative(JNIEnv *env, jobject object) { pthread_mutex_lock(&(nat->thread_mutex)); + nat->running = false; + if (nat->pollData) { LOGW("trying to start EventLoop a second time!"); pthread_mutex_unlock( &(nat->thread_mutex) ); @@ -703,6 +707,7 @@ static void stopEventLoopNative(JNIEnv *env, jobject object) { nat->controlFdW = 0; close(fd); } + nat->running = false; pthread_mutex_unlock(&(nat->thread_mutex)); #endif // HAVE_BLUETOOTH } @@ -713,7 +718,7 @@ static jboolean isEventLoopRunningNative(JNIEnv *env, jobject object) { native_data_t *nat = get_native_data(env, object); pthread_mutex_lock(&(nat->thread_mutex)); - if (nat->pollData) { + if (nat->running) { result = JNI_TRUE; } pthread_mutex_unlock(&(nat->thread_mutex)); -- cgit v1.1