0

Sendmail 用の milter を開発する必要があり、どの言語/フレームワークを使用するかについて長い間考えてきました。最後に、milter API を直接使用してプレーン C で実行することにしました。

milter API のドキュメントを読んで、概念を理解したと思います。しかし、私が非常に心配していることが1つあります。このセクションから:

1 つのフィルタ プロセスで、任意の数の接続を同時に処理できます。したがって、すべてのフィルタリング コールバックは再入可能である必要があり、適切な外部同期メソッドを使用してグローバル データにアクセスします [...]。

コールバックがスレッドセーフでなければならない理由はよく理解できますが、再入可能でなければならない理由はわかりません。これらのコールバックが割り込みまたはシグナル ハンドラから呼び出されるとは想像できません (おそらく、アボート コールバックを除いて、これを読み直す必要があります)。

再入可能であるという要件の問題は、再入可能関数が再入可能でないコードを呼び出してはならないことです。したがって、コールバックが本当に再入可能malloc()である必要がある場合は、そこにある他のほとんどのライブラリ関数を使用できませんでした。からman 3 malloc:

マルチスレッド アプリケーションでの破損を回避するために、ミューテックスが内部で使用され、これらの関数で使用されるメモリ管理データ構造が保護されます [...]

これは確かにそれmalloc()がスレッドセーフであることを意味し、おそらくmalloc()再入可能ではないことを意味するため、それを使用する関数はありません。

だから私は2つの質問があります:

1) milter コールバックは本当に再入可能である必要がありますか? それとも、これは milter API ドキュメントの「スレッドセーフである必要がある」という非常に奇妙な言い回しですか?

2) 本当に再入可能にする必要がある場合、上記の問題をどのように回避できますか? malloc()milter API の特性上、再入不可のライブラリ関数を使用せずにコールバックで合理的なことを行う方法はほとんど想像できません。

4

1 に答える 1