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 がどうなったか見ていくことにしよう。