--- nono/host/signalthread.cpp 2026/04/29 17:05:11 1.1 +++ nono/host/signalthread.cpp 2026/04/29 17:05:15 1.1.1.2 @@ -30,8 +30,11 @@ // // o SIGHUP、SIGPIPE、SIGUSR1、SIGUSR2 はデフォルトがプロセス終了なので // ブロックして無視する。 -// このうち無難そうな SIGPIPE をこのスレッドへのメッセージ通知として使う。 -// SIGPIPE 発生時に特定のメンバ変数がセットされているとそれに従って +// +// o SIGIO は、通常は非同期 I/O アクセスのハンドラとしてアプリケーションが +// これを使うことが想定されており、つまりライブラリが勝手に差し替えたり +// しないはずなので、これをこのスレッドへのメッセージ通知として使う。 +// SIGIO 発生時に特定のメンバ変数がセットされているとそれに従って // アクションを起こす。 // // Linux (Ubuntu 20.04) ではシグナルの配送が POSIX とは異なっているらしく、 @@ -81,6 +84,7 @@ static std::vector siglist_always = SIGHUP, // ignore SIGPIPE, // ignore SIGTERM, // プロセス終了 + SIGIO, // コマンド通知に使う SIGUSR1, // ignore SIGUSR2, // ignore }; @@ -128,6 +132,11 @@ SignalThread::ThreadRun() // sigwait() は成功なら 0、失敗ならエラーコードを返す。 putmsg(2, "sigwait..."); r = sigwait(&waitset, &signo); + // 終了要求が立っていたら、どのシグナルでも、エラーが起きてても + // とにかく先にスレッドを終了する。 + if (request_terminate) { + break; + } if (r != 0) { if (r == EINTR) { continue; @@ -138,27 +147,22 @@ SignalThread::ThreadRun() } putmsg(1, "sigwait got %d", signo); - // 終了要求が立っていたら、どのシグナルでもスレッドを終了する - if (request_terminate) { - break; - } - // ここからシグナル別の処理 switch (signo) { - case SIGPIPE: // コマンド + case SIGIO: // コマンド { // 本来は無視するだけなので、ついでにこのスレッドに対する // メッセージ通知として使用する。フラグが立ってなければ単に無視。 // - // SIGPIPE 発生時に request_wpipe が非負なら、HostCOM からの + // SIGIO 発生時に request_wpipe が非負なら、HostCOM からの // パイプ接続もしくは切断の要求。 int req = request_wpipe.exchange(-1); if (req >= 0) { if (loglevel >= 1) { if (req == INT_MAX) { - putmsg(1, "SIGPIPE: HostCOM del"); + putmsg(1, "SIGIO: HostCOM del"); } else { - putmsg(1, "SIGPIPE: HostCOM add %d", req); + putmsg(1, "SIGIO: HostCOM add %d", req); } } // HostCOM スレッドへのシグナル通知を変更 @@ -217,7 +221,7 @@ SignalThread::Terminate() // フラグを立ててシグナルで通知 request_terminate = true; - Kill(SIGPIPE); + Kill(SIGIO); } // HostCOM スレッドへのパイプを接続する (HostCOM スレッドから呼ばれる) @@ -234,7 +238,7 @@ SignalThread::AddPipe(int fd) } else { // スレッド開始後なら、フラグを立ててシグナルで通知 request_wpipe = fd; - Kill(SIGPIPE); + Kill(SIGIO); } } @@ -246,7 +250,7 @@ SignalThread::DeletePipe() // フラグを立ててシグナルで通知 request_wpipe = INT_MAX; - Kill(SIGPIPE); + Kill(SIGIO); } // シグナルをパイプに再配送する @@ -359,6 +363,7 @@ SignalThread::Mask(int how, int signo) CHECK(PIPE); CHECK(TERM); CHECK(TSTP); + CHECK(IO); CHECK(USR1); CHECK(USR2);