|
|
|
| 2008/10/07 11:42||▲
|
|
|
raise関数は、明示的にシグナルを発生させるための関数です。非同期シグナルに対する処理とは異なり、raise関数と、raise関数を内部的に呼び出すabort関数によって呼び出されたシグナル処理ルーチンは、そこで行うことができる処理にほとんど制約がありません。
非同期シグナルの場合、シグナル処理ルーチンの中で呼び出せる標準関数は、abort関数と_Exit関数、そして同じシグナルに対するsignal関数だけです。今回の実装では、非同期シグナルは、タスク例外処理ルーチンからraise関数を呼び出すことで実現しますが、非同期の場合はraise関数を使っていても上記の制約があるものとします。
つまり、タスク例外処理ルーチンを介して呼び出されたシグナル処理ルーチンからは、ほとんどの標準関数を呼び出すことができず、longjmp関数を用いて脱出することもできなくなります。
ところで、前回のsignal関数の回には、raise関数をsignal関数と同じ翻訳単位に入れることを想定していましたが、よく考えてみるとその必要はなさそうです。では、実装をご覧ください。
#include <kernel.h> #include <signal.h>
int raise(int sig) { void (*func)(int) = signal(sig, SIG_DFL); uintptr_t f = (uintptr_t)func; if (f <= 2) { switch (f) { case 0: // SIG_DFL ext_tsk(); // break; case 1: // SIG_IGN break; default: return -1; } } else { (*func)(sig); } return 0; }
今回の実装では、SIG_DFLの処理は、問答無用でタスク終了としています。最初からswitch文で処理を分けてもよかったのですが、ユーザー定義のシグナル処理ルーチンを最速の方法で呼び出すには、いったんユーザー定義のものが登録されているのか、SIG_DFLやSIG_IGNが登録されているのかを「ふるい」にかけた方が得策と考えて、このように実装してみました。
|
| 2006/05/22 03:15|シグナル処理|TB:0|CM:0|▲
|
|
|
コメント
|
|
コメントの投稿
|
|
|
|
|
トラックバック
|
トラックバックURLはこちら
http://libc.blog47.fc2.com/tb.php/55-c26ce81f
|
|
|
|
|
ホーム
全記事一覧
<< 前の記事
次の記事 >>
|