Hello,

I've stumbled upon a really weird problem that I can't make any sense of 
whatsoever. A little bit of backstory first:

I'm trying to run JavaScriptCore and using it as a scripting language of 
sorts for an Android app. The trouble is, stack size on the main thread is 
quite limited on older Android versions (something like 12k on API 16). 
However, I would still like to call into JS on the main thread, have it 
call back to request things and have all of that appear synchronous. No 
problem - I'll whip out a couple of channe... khm... SynchronousQueues and 
bounce the execution back and forth. Here's what my code looks like. 
<https://gist.github.com/IvayloDankolov/338df53976d6745f02448e5088ace6e5>

It's pretty simple - every time something calls defer - it bounces to the 
other thread and continues from there. The only problem is, well, it 
doesn't work. On a real use case with executing Javascript code it just 
fails pretty reliably at some point, though not at the same spot for the 
emulator and different devices. Logcat always looks pretty innocuous:

I/JavaScriptCore: Lockstep [Main]: Defer
I/JavaScriptCore: Lockstep [Main]: Send EXECUTE_FUNC
I/JavaScriptCore: Lockstep [Background]: Receive EXECUTE_FUNC
I/JavaScriptCore: Lockstep [Background]: Defer
I/JavaScriptCore: Lockstep [Background]: Send EXECUTE_FUNC

However, that second EXECUTE never gets received by main, even though the 
put goes through. As far as I understand it, that should not even be 
possible with Synchronous queues. Looking at the thread dump, the 
background thread is waiting in the run loop for the next message, while 
main is sitting parked on incoming.take. No other threads are interacting 
with this.

On one of my devices I could set up a conditional breakpoint for the exact 
moment that this stops working, and I could pause it just as MAIN is 
waiting for that EXECUTE message. The message is non-null, the 
foregroundQueue at that point is working, I can poll it with or without 
timeout from Android Studio, take its size, whatever. As soon as I step 
over all the operations hang.

Of course, I suspected JNI shenanigans, but there are no memory dumps, 
segmentation faults or any warnings at all for that matter in Logcat.

Also, it's not just take - even if I do it with a really dirty busy wait:

Message msg = incoming.poll();
if(msg == null) {
 Thread.sleep(20);
 continue;
}

Main is stuck on poll, the background thread keeps merrily chugging away on 
the other queue every 20 milliseconds.

I tried nesting defers with a really lazy factorial that likes to sleep a 
lot and it has no problem going 200 deep, integer overflows notwithstanding:

LockstepThread t = new LockstepThread();

int deferredFactoriel(final int n) {
  if(n == 0) {
    return 1;
  }
  return n * t.defer(new Functor<Integer>() {
    @Override
     public Integer call() {
       try {
         Thread.sleep(20);
       } catch (InterruptedException e) {
         e.printStackTrace();
       }
       return deferredFactoriel(n-1);
    }
  });
}

@Override
public void onCreate() {

  super.onCreate();

  for(int i=0; i<200; ++i) {
    Log.i("Test", i+"! = " + deferredFactoriel(i));
  }

...

What is probably strangest of all, is that it doesn't matter what 
synchronisation I use. SynchronizedQueue, ArrayBlockingQueue, 
LinkedBlocking queue - it always fails at the same spot with the exact same 
thread dump. Hell, I even made my own exchanger 
<https://gist.github.com/IvayloDankolov/999f8ebd262144f519003678c55ec533> just 
to see that I'm not going insane and it still got stuck in the same way.


So yeah, I'm completely stumped. Any ideas what's going on? Any help with 
debugging this would be much appreciated.

-- 
You received this message because you are subscribed to the Google Groups 
"Android Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at https://groups.google.com/group/android-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/android-developers/c7cc7ed0-27ea-47e4-a61c-d880d97b9eb0%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to