Merge "Workaround for bug 5082381 (EALREADY on ACL collision)."

This commit is contained in:
Nick Pelly
2011-07-29 09:44:30 -07:00
committed by Android (Google) Code Review

View File

@@ -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);