client_acceptor.h において、私達は そのオブジェトを少しだけ拡張した。その理由の一つ目はシングルスレッド実装の他に スレッドパーコネクション実装が使えるようにすることだった。 Clietn_Acceptor 自身はその情報を使わないが、Client_Handler オブジェクトを 作成して利用する際に必要になるからである。 もし一つの実装しか使わないのであれば、このファイルはチュートリアル5のものから 変更する必要はなかった。
// $Id$ #ifndef CLIENT_ACCEPTOR_H #define CLIENT_ACCEPTOR_H /* ACE_Acceptor<> テンプレートは ace/Acceptor.h ヘッダーファイルに 書かれている。ACE オブジェクトと、それが書かれているヘッダーファイルは 明確な名前付け規則に従っている。一般的に、ACE_Foobar オブジェクトは ace/foobar.h ファイルの中に見付けることができる。 */ #include "ace/Acceptor.h" #if !defined (ACE_LACKS_PRAGMA_ONCE) # pragma once #endif /* ACE_LACKS_PRAGMA_ONCE */ /* ソケットを利用するので、クライアントからの接続を許可するために SOCK_Acceptor が必要になる。 */ #include "ace/SOCK_Acceptor.h" /* これから作成する Client_Handler オブジェクトは、一度クライアントと 接続されると、その面倒を見続ける。ACE_Acceptor<> テンプレートの 最初のパラメータは、このオブジェクトを参照する。そのため、 いくつかのケースではクラスへの前方参照を指定し、その他の場合には 完全な定義を行うことになるだろう。 */ #include "client_handler.h" /* ソケット接続を待ち、それに応じて Client_Handler オブジェクトを割り当てる ように ACE_Acceptor<> クラスをパラメータ化する。 チュートリアル 001 では ACE_Acceptor<> を知らなかったので 自前の標準的な受け付けロジックを書くことになった。 ACE テンプレートを利用することで、このようなつまらない詳細部分を 省いてプログラムを書くことができる。 */ typedef ACE_Acceptor <Client_Handler, ACE_SOCK_ACCEPTOR> Client_Acceptor_Base; /* ここでパラメータ化した ACE_Acceptor<> を基本クラスとして カスタマイズした Client_Acceptor オブジェクトを準備する。 我々は既に、オブジェクトの作成時に並行性戦略を選択できるように 準備を整えておいた。それぞれの Client_Handler は、作成時に与えられた 情報をもとにして、どのように動くべきかを決定する。 もし我々の目的が、常にスレッドパーコネクションで動くシステムの構築ならば このような Client_Acceptor の拡張は不要だっただろう。 */ class Client_Acceptor : public Client_Acceptor_Base { public: /* これは常に良いアイデアである。もし無かった場合に比べると、これのおかげで オブジェクトの基本クラスが分かり、より直交したコードになっている。 */ typedef Client_Acceptor_Base inherited; /* 並行性戦略を指定してオブジェクトを作成する。このチュートリアルが スレッドパーコネクションに焦点を合わせているため、そちらをデフォルトにする。 もちろん、デフォルトをやめて別の設定を main() で利用することもできる。 */ Client_Acceptor (int thread_per_connection = 1) : thread_per_connection_ (thread_per_connection) { } /* 並行性戦略のフラグを返す。これは Client_Handler がどのように動くかを 決める時に利用される。もし、真(訳注:この場合は0以外)であれば、ハンドラは スレッドパーコネクションとして振る舞う。 */ int thread_per_connection (void) { return this->thread_per_connection_; } protected: int thread_per_connection_; }; #endif /* CLIENT_ACCEPTOR_H */
これでよし。並行戦略を変更するための作業はそう多くは必要なかった。 それでは Client_Handler がどうなったか見ていくことにしよう。