ACE Tutorial 006
Creating a thread-per-connection server


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


[インデックスへ] [次へ進む]