2013-09-30 13 views
5

ネイティブコードを処理するJavaサーバー(Linux 64ビット)アプリケーションがあります。ネイティブコードでは、すべてのマルチスレッドの問題も処理され、最近ではboost::contextを使用してファイバ交換で強化されています。コンテキスト切り替えネイティブスレッドはJVMにアタッチできません

今直面している問題は、AttachCurrentThreadがファイバ交換スレッドで失敗することです。いくつかの長いデバッグとテストセッションの後、私たちはこれの原因を発見しました.JVMは、作成時に与えられたものとは異なるスタックポインタを持つスレッドを拒否しているようです。

rspが変更されたときに変更された(しかし有効な)rspを持つpthreadからJVMに接続するだけで、これを確認できました。

可能な修正では、コールバックをファイバ交換スレッドから切り離すための何らかのイベント処理メカニズムが導入される可能性がありますが、これを避けたいと考えています。

誰かがこれに対する回避策を知っていますか?

スタックチェック(Java Java 1.7.0_40,64ビット)を無効にすることはできますか?

正しいスタックフレームを指すようにネイティブpthreadを変更できますか? (スタックフレームはあらかじめ設定することはできません)。

+1

私はそれがあなたの問題に正確に答えていないことを知っていますが、あなたはboost :: contextファイバー(C++で実装されている)をJavaの世界のファイバーの実装に置き換えることができます。この文脈では、多くの場合コルーチンと呼ばれます。 ここにいくつかの既存の実装があります:[Javaで利用可能なコルーチンライブラリ](http://stackoverflow.com/questions/2846428/available-coroutine-libraries-in-java) –

+0

これに対する解決策はありますか?私はBoost.Coroutineを利用しようとしており、そのようなルーチンでJNIからJava空間にコールバックする必要があります。その結果、多くの失敗が発生します... – NuSkooler

答えて

0

免責事項:私はRSPスイッチの問題に直接対処していないため、これは実際の回答ではありませんが、コメントに入れるには時間がかかりすぎました。

私の経験では、ネイティブスレッドを正確に1回接続し、終了する前に正確に1回切り離す必要があります。あなたは正確に一度の任意の関連する繊維が作成される前に、スレッドにアタッチしていることを確認して、

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

私が最初に提案し、そしてから一度正確に切り離す:あなたはすでに添付しましたかどうかわからない場合、このコードを使用しますそれが出る前の各ネイティブスレッド(またはネイティブスレッドが終了しない場合はまったくありません)。

関連する問題