コンテキストの終了

様々なTruffle(ゲスト)言語では、終了のために異なるメカニズムが使用されることがあります。Truffle言語には、別の言語によってトリガーされた終了を検出して処理する方法がないため、これは最適ではありません。

Truffle 22.0では、ゲスト言語がTruffleContext.closeExited(Node,int)を使用してトリガーした、ポリグロット・コンテキストの明示的なハード終了がサポートされます。これで、基礎となるポリグロット・コンテキストの終了を言語がトリガーするための統一された方法が提供されます。トリガーされると、初期化済のすべてのゲスト言語にTruffleLanguage.exitContext(C,ExitMode,int)を使用して最初に通知され、次にすべてのコンテキスト・スレッドが停止され、最後にコンテキストがクローズされます。明示的ハード終了は単に「ハード終了」と呼ばれます。

ハード終了は、Truffleの3つのタイプの終了のうちの1つです。次のタイプの終了があります。

完全性を保つため、ポリグロット・コンテキストは、Context.close(true)TruffleContext.closeCancelled(Node,String)、またはTruffleContext.closeResourceExhausted(Node,String)を使用して取り消すことでもクローズできます。取消し操作では、すべてのコンテキスト・スレッドがすぐに停止され、終了通知なしでコンテキストがクローズされます。

ソフト終了

ソフト終了は、例外タイプExceptionType.EXIT (ソフト終了例外)のTruffle例外をスローすることによってトリガーされます。例外は、他のスレッドでTruffleによって自動的にスローされることはありません。また、それだけで終了通知またはコンテキスト・クローズをトリガーすることはありません。言語がソフト終了例外を捕捉できなかった場合でも、最終的にソフト例外によって、埋込み側スレッドがPolyglotExceptionをホストにスローします。これには、PolyglotException.isExit() == truePolyglotException.getExitStatus() (ソフト終了例外に指定された値と等価)が含まれます。

ソフト終了後、コンテキストは完全に使用可能です。ただし、埋込み側は、PolyglotException.isExit() == truePolyglotExceptionを確認したときにコンテキストをクローズする必要があります。この場合、ソフト終了の後に自然終了が続くためです。

自然終了

自然終了スキーマ

自然終了は、Context.close()またはTruffleContext.close()によってトリガーされる通常のコンテキスト・クローズ中に発生します。上の図に示す自然終了は、次のステップで構成されています:

  1. 自然終了は、Context.close()またはTruffleContext.close()によってトリガーされます。

  2. 初期化済のすべての言語に対して終了通知が実行されます - TruffleLanguage.exitContext(C,ExitMode,int) (ExitMode.NATURALExitModeパラメータとして使用されます)。
    • ゲスト・コードは、終了通知中に正常に実行されます。
  3. 初期化されたすべての言語がファイナライズされます。
    • TruffleLanguage.finalizeContext(C)が、すべての初期化済言語に対してコールされます。
    • ゲスト・コードは、ファイナライズ中に正常に実行されます。
  4. すべての言語が破棄されます。
    • TruffleLanguage.disposeContext(C)が、すべての言語に対してコールされます。

ハード終了

ハード終了スキーマ

この項では、ハード終了のプロセスについて詳しく説明します。ポリグロット・コンテキストのハード終了は、Context.Builder.useSystemExit(boolean)を使用してカスタマイズできます。このため、次の説明はさらに2つの項に分かれています。1つはシステム終了が有効になっていないケース(Context.Builder.useSystemExit(false) - デフォルト)、もう1つはシステム終了が有効になっているケース(Context.Builder#useSystemExit(true))に対応しています。終了プロセスの図は、上の図に示されています。また、この図では、終了プロセスがコンテキスト取消しプロセスに関連付けられています。いくつかの枠が赤色になっているのは、その時点でコンテキストが無効であり、ゲスト・コードを実行できないことを示します。詳しく説明すると、最初のTruffleセーフポイントが、ハード終了操作または取消し操作のどちらが進行中かに応じて、特別なThreadDeath終了例外または特別なThreadDeath取消し例外をスローします。

useSystemExitが無効な場合の動作(デフォルト)

  1. 終了はTruffleContext.closeExited(Node,int)によってトリガーされます。

  2. 初期化済のすべての言語に対して終了通知が実行されます - TruffleLanguage.exitContext(C,ExitMode,int) (ExitMode.HARDExitModeパラメータとして使用されます)。
    • ゲスト・コードは、終了通知中に正常に実行されます。
    • コンテキストが終了通知(ステップ2a)の間に取り消されずに、ステップ2bまで進んだ場合、終了プロセスが次のステップに進みます。それ以外の場合、終了通知は中断され、コンテキストがただちに取り消されます。
  3. すべてのコンテキスト・スレッドは、特別なThreadDeath終了例外をTruffleセーフポイントからスローして、強制的に停止されます。
    • スレッドを確実に終了するには、ThreadDeathが常にすぐ再スローされること、ゲスト言語の例外ハンドラが実行されないこと、また最終的にブロックが実行されないことが、言語によって保証される必要があります。
    • 最終的に埋込み側スレッドがPolyglotExceptionをスローします。これには、PolyglotException.isExit() == trueと、PolyglotException.getExitStatus() (最初のTruffleContext.closeExited(Node,int)へのコールの2番目のパラメータに指定された終了コードと等価)が含まれます。
    • 図に示すように、ステップ3以降の終了プロセスは取消しプロセスと似ています。ただし、取消しプロセスでは特別なThreadDeath取消し例外が使用され、ホストにスローされるPolyglotExceptionPolyglotException.isExit() == trueではなくPolyglotException.isCancelled() == trueが含まれます。
  4. 初期化されたすべての言語がファイナライズされます。
    • TruffleLanguage.finalizeContext(C)が、すべての初期化済言語に対してコールされます。
    • TruffleLanguage.finalizeContext(C)でゲスト・コードを実行すると、特別なThreadDeath終了例外が最初のTruffleセーフポイントからスローされます。
    • 言語は、ゲスト・コードの実行が必要となるファイナライズをスキップする必要があります。言語がゲスト・コードをTruffleLanguage.finalizeContext(C)で実行できるかどうかは、TruffleLanguage.exitContext(C,ExitMode,int)が前にExitMode.NATURALを使用してコールされたかどうかを確認するか、TruffleContext.isClosed()によってfalseが返されるかを確認することで調べられます。
  5. すべての言語が破棄されます。
    • TruffleLanguage.disposeContext(C)が、すべての言語に対してコールされます。
  6. コンテキストがクローズされます。

useSystemExitが有効な場合の動作

  1. 終了はTruffleContext.closeExited(Node,int)によってトリガーされます。
    • システム終了が無効な場合と同じ。
  2. 初期化済のすべての言語に対して終了通知が実行されます - TruffleLanguage.exitContext(C,ExitMode,int) (ExitMode.HARDExitModeパラメータとして使用されます)。
    • システム終了が無効な場合と同じ。
  3. System.exit(int)がコールされ、ホスト・アプリケーション全体を終了し、できるかぎり早く終了できるようにします。
    • System.exit(int)に渡される終了コードは、TruffleContext.closeExited(Node,int)への最初のコールに2番目のパラメータとして指定された終了コードです。

使用例

SimpleLanguageでは、ハード・コンテキスト終了の使用方法について説明されます。次の内容について説明されます。