Pepper API 7 Emulator in Android Studio Spawning Too Many Threads?

Viewed 108

I'm using the Pepper plugin on Android Studio. I have the robot emulator and device emulator running fine, but when I run the application, I get this weird threadpool spawning error. I've gone through the entire install tutorial and made sure everything was right, but I can't get around this. It happens most of the times that I run it, but sometimes it runs without any issues. Thanks!

07-29 11:38:29.474 2625-2643/com.tammy.tammygame E/qi.eventloop: Threadpool MainEventLoop: System seems to be deadlocked, sending emergency signal
07-29 11:38:29.474 2625-2643/com.tammy.tammygame A/qimessaging.jni: Emergency, aborting
07-29 11:38:29.474 2625-2631/com.tammy.tammygame I/art: Thread[3,tid=2631,WaitingInMainSignalCatcherLoop,Thread*=0xa682e700,peer=0x12c790a0,"Signal Catcher"]: reacting to signal 3
07-29 11:38:29.479 2625-2631/com.tammy.tammygame W/art: Method processed more than once: android.os.Message android.os.MessageQueue.next()
07-29 11:38:29.483 2625-2631/com.tammy.tammygame W/art: Method processed more than once: void java.lang.Daemons$ReferenceQueueDaemon.run()
07-29 11:38:29.484 2625-2631/com.tammy.tammygame W/art: Method processed more than once: java.lang.ref.Reference java.lang.ref.ReferenceQueue.remove(long)
07-29 11:38:29.484 2625-2631/com.tammy.tammygame W/art: Method processed more than once: boolean java.lang.Daemons$FinalizerWatchdogDaemon.waitForObject()
07-29 11:38:29.486 2625-2631/com.tammy.tammygame W/art: Method processed more than once: void java.lang.Daemons$HeapTaskDaemon.run()
07-29 11:38:29.490 2625-2631/com.tammy.tammygame W/art: Method processed more than once: void java.util.Timer$TimerImpl.run()
07-29 11:38:29.497 2625-2631/com.tammy.tammygame E/art: Unable to open stack trace file '/data/anr/traces.txt': No such file or directory
07-29 11:38:29.976 2625-2643/com.tammy.tammygame I/qi.eventloop: Threadpool MainEventLoop: Size limit reached (658 timeouts / 20 max, number of tasks: 690, number of active tasks: 8, number of threads: 8, maximum number of threads: 8)
07-29 11:38:29.976 2625-2643/com.tammy.tammygame E/qi.eventloop: Threadpool MainEventLoop: System seems to be deadlocked, sending emergency signal
07-29 11:38:29.976 2625-2643/com.tammy.tammygame A/qimessaging.jni: Emergency, aborting```
1 Answers

The Qi SDK and its underlying framework, libQi, produce threads automatically for your callbacks (for subscriptions of future continuations). But this is limited in hard code to 8 threads for Android clients, which is not so much. When they are all busy, the communication with the robot is blocked, and apparently the program is aborted too.

To avoid this kind of issue you must be cautious of the code you write in these callbacks (onRobotFocusGained is also one of them), and avoid blocking code there. To do so, remember to always call Qi SDK methods via asynchronous interfaces, for instance say.async().run() instead of say.run(). That would return a Future f, and the continuation of your code would land in the callback of f.andThen(...).

If you are using Kotlin, you can avoid this tiresome gymnastic by using coroutines, via suspend functions. A suspend awaiting a result from a future would stop there, freeing the thread, and resume execution upon receiving the result. Qi's notion of Future is compatible with coroutines. Here is a file you can put in your project to extend Qi's Future for coroutines. With this, you can call say.async().run().await() and wait for the result without blocking the thread. Yet, it looks synchronous, so it is convenient for you as a developer.

Related