diff options
| author | 2011-07-29 09:44:30 -0700 | |
|---|---|---|
| committer | 2011-07-29 09:44:30 -0700 | |
| commit | 5ff1c1591fc5abfdd00ebbce724445661fcc384d (patch) | |
| tree | 081553d6efe32ed351236ec86eec7139d09bf9cf | |
| parent | 6619852ecd9b32aca92226a94ab497a6582e8baa (diff) | |
| parent | fbbea2e1bf85bbee28fe86d1cf912929a8d09f6f (diff) | |
Merge "Workaround for bug 5082381 (EALREADY on ACL collision)."
| -rw-r--r-- | core/jni/android_bluetooth_BluetoothSocket.cpp | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/core/jni/android_bluetooth_BluetoothSocket.cpp b/core/jni/android_bluetooth_BluetoothSocket.cpp index 4c84324af266..488b5c249a50 100644 --- a/core/jni/android_bluetooth_BluetoothSocket.cpp +++ b/core/jni/android_bluetooth_BluetoothSocket.cpp @@ -57,6 +57,9 @@ static const int TYPE_L2CAP = 3; // TODO: Test l2cap code paths static const int RFCOMM_SO_SNDBUF = 70 * 1024; // 70 KB send buffer +static void abortNative(JNIEnv *env, jobject obj); +static void destroyNative(JNIEnv *env, jobject obj); + static struct asocket *get_socketData(JNIEnv *env, jobject obj) { struct asocket *s = (struct asocket *) env->GetIntField(obj, field_mSocketData); @@ -172,6 +175,7 @@ static void connectNative(JNIEnv *env, jobject obj) { socklen_t addr_sz; struct sockaddr *addr; struct asocket *s = get_socketData(env, obj); + int retry = 0; if (!s) return; @@ -226,10 +230,30 @@ static void connectNative(JNIEnv *env, jobject obj) { return; } +connect: ret = asocket_connect(s, addr, addr_sz, -1); LOGV("...connect(%d, %s) = %d (errno %d)", s->fd, TYPE_AS_STR(type), ret, errno); + if (ret && errno == EALREADY && retry < 2) { + /* workaround for bug 5082381 (EALREADY on ACL collision): + * retry the connect. Unfortunately we have to create a new fd. + * It's not ideal to switch the fd underneath the object, but + * is currently safe */ + LOGD("Hit bug 5082381 (EALREADY on ACL collision), trying workaround"); + usleep(100000); + retry++; + abortNative(env, obj); + destroyNative(env, obj); + initSocketNative(env, obj); + if (env->ExceptionOccurred()) { + return; + } + goto connect; + } + if (!ret && retry > 0) + LOGD("...workaround ok"); + if (ret) jniThrowIOException(env, errno); |