c - Android and JNI real time clock -


i got problem mini android application , use of real time clock signals in c (jni) function.

it seems android ui doesn't real time signals timers instanced in c function.

in following poc, timer trigger signal 5 times per second , if signal triggered while ui updating, application crashes.

  • if don't start timer => no crash
  • if don't put on ui => no crash

i wrote little poc evidence behaviour. java part call jni function , put button on screen.

public class mainactivity extends appcompatactivity {      button bt;      static {         system.loadlibrary("testtimer-jni");     }      /* jni ingresso */     public native void jnistarttimer();      @override     protected void oncreate(bundle savedinstancestate) {         super.oncreate(savedinstancestate);          jnistarttimer();          /* load button */         bt = new button(getbasecontext());          setcontentview(bt);     } }     

and main.c file content. timer instanced , started. every 200ms (5 times per sec) cb() function called.

#include <jni.h> #include <android/log.h> #include <signal.h> #include <time.h> #include <strings.h>  timer_t           timer_id = 0x12; struct itimerspec timer; struct sigevent   te; struct sigaction  sa;  void cb(int sig, siginfo_t *si, void *uc) {     __android_log_write(android_log_error, "test", "called callback"); }  void java_it_dbtecno_testtimer_mainactivity_jnistarttimer(jnienv *env, jobject thiz) {     __android_log_write(android_log_error, "test", "timer inited");      /* prepare timer emulate video refresh interrupts */     sa.sa_flags = sa_siginfo;     sa.sa_sigaction = cb;     sigemptyset(&sa.sa_mask);      if (sigaction(sigrtmin + 7, &sa, null) == -1)         return;     bzero(&te, sizeof(struct sigevent));      /* set , enable alarm */     te.sigev_notify = sigev_signal;     te.sigev_signo = sigrtmin + 7;     te.sigev_value.sival_ptr = &timer_id;     timer_create(clock_realtime, &te, &timer_id);      timer.it_value.tv_sec = 1;     timer.it_value.tv_nsec = 1000;     timer.it_interval.tv_sec = 0;     timer.it_interval.tv_nsec = 1000000000 / 5;      /* start timer */     timer_settime(timer_id, 0, &timer, null); } 

sometimes dies instantly, dies after press button (i think depends on timing of signal/ui update) , output on log

09-22 11:52:12.087 13587-13587/it.dbtecno.testtimer i/test: called callback 09-22 11:52:12.288 13587-13587/it.dbtecno.testtimer i/test: called callback 09-22 11:52:12.501 13587-13587/it.dbtecno.testtimer i/test: called callback 09-22 11:52:12.532 13587-13587/it.dbtecno.testtimer a/openglrenderer: task in queue! 09-22 11:52:12.532 13587-13587/it.dbtecno.testtimer a/libc: fatal signal 6 (sigabrt), code -6 in tid 13587 (tecno.testtimer) 09-22 11:52:12.637 1187-1187/? a/debug: *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 09-22 11:52:12.637 1187-1187/? a/debug: build fingerprint: 'android/sdk_google_phone_x86/generic_x86:6.0/master/3079352:userdebug/test-keys' 09-22 11:52:12.637 1187-1187/? a/debug: revision: '0' 09-22 11:52:12.637 1187-1187/? a/debug: abi: 'x86' 09-22 11:52:12.638 1187-1187/? a/debug: pid: 13587, tid: 13587, name: tecno.testtimer  >>> it.dbtecno.testtimer <<< 09-22 11:52:12.638 1187-1187/? a/debug: signal 6 (sigabrt), code -6 (si_tkill), fault addr -------- 09-22 11:52:12.642 1187-1187/? a/debug: abort message: 'task in queue!' 09-22 11:52:12.642 1187-1187/? a/debug:     eax 00000000  ebx 00003513  ecx 00003513  edx 00000006 09-22 11:52:12.642 1187-1187/? a/debug:     esi b77a5c50  edi 0000000b 09-22 11:52:12.642 1187-1187/? a/debug:     xcs 00000073  xds 0000007b  xes 0000007b  xfs 00000007  xss 0000007b 09-22 11:52:12.642 1187-1187/? a/debug:     eip b736f666  ebp 00003513  esp bfdc7540  flags 00200202 09-22 11:52:12.644 1187-1187/? a/debug: backtrace: 09-22 11:52:12.645 1187-1187/? a/debug:     #00 pc 00084666  /system/lib/libc.so (tgkill+22) 09-22 11:52:12.650 1187-1187/? a/debug:     #01 pc 00081608  /system/lib/libc.so (pthread_kill+70) 09-22 11:52:12.651 1187-1187/? a/debug:     #02 pc 00027205  /system/lib/libc.so (raise+36) 09-22 11:52:12.651 1187-1187/? a/debug:     #03 pc 000209e4  /system/lib/libc.so (abort+80) 09-22 11:52:12.659 1187-1187/? a/debug:     #04 pc 0000cbc3  /system/lib/libcutils.so (__android_log_assert+128) 09-22 11:52:12.660 1187-1187/? a/debug:     #05 pc 00025e81  /system/lib/libhwui.so (android::uirenderer::renderthread::renderthread::queue(android::uirenderer::renderthread::rendertask*)+81) 09-22 11:52:12.660 1187-1187/? a/debug:     #06 pc 00021b44  /system/lib/libhwui.so 09-22 11:52:12.660 1187-1187/? a/debug:     #07 pc 000243e5  /system/lib/libhwui.so (android::uirenderer::renderthread::renderproxy::syncanddrawframe()+29) 09-22 11:52:12.660 1187-1187/? a/debug:     #08 pc 000ba75b  /system/lib/libandroid_runtime.so 09-22 11:52:12.660 1187-1187/? a/debug:     #09 pc 72dfe20e  /data/dalvik-cache/x86/system@framework@boot.oat (offset 0x1eb2000) 09-22 11:52:12.713 1187-1187/? a/debug: tombstone written to: /data/tombstones/tombstone_08 09-22 11:52:12.713 1187-1187/? e/debug: write failed: broken pipe 

i tried change signal number (from sigrtmin sigrtmin + 20) no luck....

my question is.... possible use real time clock signals in jni function without breaking renderthread? (yes, it's latter crashes)

is bad habit play timers in jni functions?

probably timer signal delivered renderer thread or main thread. in such case interrupts system call in progress in thread (if any). , situation may trigger assert in runtime code. may play sigev_thread_id direct signal dedicated thread. aware notification type not intended widespread usage. of real-time signals may silently used bionic threading implementation or art. easy break something.

p.s. if possible - should prefer sigev_thread. looks more reliable on android since shouldn't think proper signal numbers etc.


Comments

Popular posts from this blog

unity3d - Rotate an object to face an opposite direction -

angular - Is it possible to get native element for formControl? -

javascript - Why jQuery Select box change event is now working? -