Open a-thomas opened 12 years ago
Were you able to solve this problem? We have the same issue now.
Hi I've never working on android before. Do you guys have any tips on how I can setup a testing environment that I can #1 reproduce the issue, and #2 attach a debugger against?
FYI I think the problem is that in the apache harmony version, calling 'keys' returns an UnmodifiableSet[1](which I believe is threadsafe) and the java.nio.Selector documentation[2] says that keys is not threadsafe. Is this in the hawtdispatch code? I believe wrapping all concurrent thread usage of the keys object would a ConcurrentSet might fix the problem.
If you can reproduce the deadlock on your phone, you should be able to see the other thread that is holding the lock using DDMS (ddms is a tool available in the android-sdk installation, attach your phone, start ddms, select your phone and app, then click threads).
[1]http://www.docjar.com/html/api/org/apache/harmony/nio/internal/SelectorImpl.java.html line 83 [2]http://docs.oracle.com/javase/1.4.2/docs/api/java/nio/channels/Selector.html#keys()
I believe wrapping all concurrent thread usage of the keys object would a ConcurrentSet might fix the problem.
Also I have seen this issue on the new Nexus phones running ICS (Android 4.0), the Galaxy Tablet running Android 3.0, but not on a Nexus S (older generation) running ICS. So to repro, i believe it is best to use the new Nexus or the Galaxy Tab (or emulator)
screenshot of deadlock
I believe the problem is in this code.
We query the selector to determine the # of keys, but we have another thread accessing the same selector calling park. According to http://rox-xmlrpc.sourceforge.net/niotut/ (and the JDK documentation) these objects aren't threadsafe.
On an android device, we're almost certainly going to be dealing w/ just one thread so we can probably just shortcircuit this code to pick the first (or a random) worker thread.
// otherwise.. pick the thread queue with the fewest registered selection
// keys.
if( selectorQueue.getQueueType()!=THREAD_QUEUE ) {
WorkerThread[] threads = dispatcher.DEFAULT_QUEUE.workers.getThreads();
WorkerThread min = threads[0];
int minSize = min.getNioManager().getSelector().keys().size();
for( int i=1; i < threads.length; i++) {
int s = threads[i].getNioManager().getSelector().keys().size();
if( s < minSize ) {
minSize = s;
min = threads[i];
}
}
selectorQueue = min.getDispatchQueue();
Would this occur when calling connect() on a blocking connection? This seems to be working fine in Android 4.1+ but I discovered that hanging in ICS. Was this resolved?
I develop a Mqtt-client on Android for 3.x tablet version.
My client works well with Android 2.x version but not with Android 3.x. On Android 3.x, my request is never sent to my Broker (I use Mosquitto). I debugged my project and I think I found out the problem's location:
The application blocks in the
pickThreadQueue
method of theNioDispatchSource
class at the followed line:The only difference between Android 3.x and Android 2.x is the Selector Implementation.
org.apache.harmony.nio.internal.SelectorImpl
on 2.xjava.nio.SelectorImpl
on 3.xSo, it works with apache harmony Selector implementation and not with java.nio... Have you an idea why it doesn't work ? Thanks for your answers.