2015-09-06 20 views
5

Meine Android App hat ein einfaches „loader“ Native mit einem sehr einfachen android_main(), die nur einen anderen gemeinsamen Objekt lädt und übergibt die Steuerung an sie:Race-Bedingung in Android dlopen()?

typedef void (*Tandroid_main)(android_app*); 
void android_main(android_app* state) 
{ 
    void* glib = dlopen("libmain.so", RTLD_NOW); 
    void* fmain = dlsym(glib, "android_main"); 
    Tandroid_main libmain = (Tandroid_main)fmain; 
    libmain(state) 
} 

Das gut .. etwa die Hälfte der Zeit arbeitet. Andere Male stürzt es seit dlopen() schlägt fehl und gibt NULL mit errno = 2 zurück (keine solche Datei).
Aufgrund der seltsamen Inkonsistenz dieses Auftretens vermutete ich ein Timing-Problem und in der Tat stoppte es eine sleep(1) vor dlopen() zu passieren. Etwas robuster als sleep(1) würde nur versuchen, es in einer Schleife:

int count = 0; 
void* glib = dlopen(soName, RTLD_NOW); 
while(glib == NULL) { 
    sched_yield(); 
    ++count; 
    glib = dlopen(soName, RTLD_NOW); 
} 

Die Zählung ich aus dieser Schleife bekommen ist in der Regel etwas im Bereich von 10-70 auf meinem Gerät. Aber das ist eine hässliche hässliche Lösung.

Was geht hier wirklich vor? Wieso kann ich nur nach dem Start von NativeActivity nur noch andere geteilte Objekte laden? Gibt es einen besseren Weg zu finden, wann es sicher ist, es zu laden?

Es soll beachtet werden, dass ich auch telefonieren bin System.loadLibrary("main") von meinem Native des onCreate()

Antwort

4

nicht sicher, aber es wird empfohlen, Loadlibrary() aus einem statischen Initialisierer zu nennen:

public class MainActivity extends Activity { 
    static { 
     System.loadLibrary("main") 
    } 
    ... 
} 

Hilft es?

+0

Yap, das hat es gelöst! schöner Fang :) – shoosh