2013-09-30 10 views
5

Abbiamo un'applicazione Java server (Linux a 64 bit) che utilizza il codice nativo per i suoi processi di elaborazione. Il codice nativo gestisce anche tutti i problemi di multithreading ed è stato recentemente migliorato con il cambio di fibra utilizzando boost::context.Il thread nativo con commutazione di contesto non può essere collegato a JVM

Il problema che stiamo affrontando in questo momento è che AttachCurrentThread non riesce per i thread a fibra ottica. Dopo lunghe sessioni di debug e test abbiamo trovato la causa di ciò: la JVM sembra rifiutare i thread con diversi puntatori dello stack rispetto a quelli forniti durante la sua creazione.

Abbiamo verificato ciò collegando semplicemente alla JVM da un pthread con modificato (ma valido) rsp che non riesce quando viene modificato rsp.

Una possibile correzione introduce una sorta di meccanismo di gestione degli eventi per separare i callback dai thread a fibra ottica, ma vorrei davvero evitarlo.

Qualcuno sa una soluzione alternativa per questo?

È possibile disattivare i controlli di stack (Oracle Java 1.7.0_40, 64 bit)?

Possiamo modificare i pthread nativi per puntare ai frame di stack corretti (dubito che possiamo)? (Non possiamo impostare i frame dello stack in anticipo).

+1

So che non risponde esattamente al tuo problema, ma potresti provare a sostituire il tuo boost :: context fibre (implementato in C++) con l'implementazione di alcune fibre all'interno del mondo Java. Sono spesso chiamati coroutine in questo contesto. Alcune implementazioni esistenti qui: [Librerie Coroutine disponibili in Java] (http://stackoverflow.com/questions/2846428/available-coroutine-libraries-in-java) –

+0

Hai mai trovato una soluzione a questo? Sto tentando di utilizzare Boost.Coroutine e ho bisogno di richiamare nello spazio Java di JNI in una tale routine che si traduce in molti fallimenti ... – NuSkooler

risposta

0

NOTA BENE: Questa non è una vera risposta, perché non affronta direttamente il problema dell'interruttore RSP, ma era troppo lungo per essere inserito in un commento.

Nella mia esperienza, dovresti collegare il thread nativo esattamente una volta e staccarlo esattamente una volta prima che esca. Se non si sa se è stato collegato già, di questo codice:

jint rv = vm->GetEnv((void**)&env, JNI_VERSION_1_6); 
if (rv == JNI_EDETACHED) { 
    vm->AttachCurrentThread((void**)&env, 0); 
} 

Suggerisco prima, facendo in modo che si collega al filo esattamente una volta prima di creare qualsiasi fibra associati, e staccare esattamente una volta da ogni thread nativo prima che esca (o non lo sia affatto, se i thread nativi non terminano).