ACE Tutorial 002
Creating a Better Server


チュートリアル1と同様に、今回も簡単なプログラムである。 新しいアイデアをいくつか盛り込む予定ではいるが、それで不用意に飾り立てるつもりはない。 細心の注意を払ってシンプルなアクセプタにするつもりである。

Kirthika による概要

それでは main (server.cpp) 関数からプログラムを見ていこう。


// $Id$


/*
  Logging_Handler のために必要ないくつかの ACE オブジェクトを宣言する。
*/

#include "ace/Acceptor.h"
#include "ace/SOCK_Acceptor.h"
#include "ace/Reactor.h"
#include "handler.h"


/*
  ここでもリアクタはグローバルポインタとして利用する。
  後のサーバチュートリアルで改善するので、それまで待ってほしい。
*/

ACE_Reactor *g_reactor;


/*
  これはチュートリアル1でも触れたが、アクセプタは手書きではなくテンプレートを利用して作成した方が簡単である。
  アプリケーションに直接関係無いコードを書いていると感じた時こそ ACE のコンポーネントの出番である。
*/

typedef ACE_Acceptor <Logging_Handler, ACE_SOCK_ACCEPTOR> Logging_Acceptor;


/*
  新しい項目の一つは綺麗にプログラムを終了させるためのシグナルハンドラ設定である。
  無限ループの代わりに"finished"フラグが利用され、SIGINT が(Ctrl-Cによって)発生するとハンドラがフラグを操作する。
  ACE_Reactor::notify() の呼び出しはフラグの新しい値を読み出させるために handle_events() から一度戻らせる。

static sig_atomic_t finished = 0;
extern "C" void handler (int)
{
  finished = 1;
  g_reactor->notify();
}

static const u_short PORT = ACE_DEFAULT_SERVER_PORT;

int
main (int, char **)
{
  // イベントハンドラ登録のために Reactor を生成する。
  ACE_NEW_RETURN (g_reactor,
                  ACE_Reactor,
                  1);

  // クライアントの接続要求を受け入れる acceptor を生成する。
  Logging_Acceptor peer_acceptor;

  
  /*
    この open() 呼び出しがチュートリアル1のそれと同様であることに注目してほしい。
  */

  if (peer_acceptor.open (ACE_INET_Addr (PORT),
                          g_reactor) == -1)
    ACE_ERROR_RETURN ((LM_ERROR,
                       "%p\n",
                       "open"),
                      -1);

  
  /*
    これがアプリケーションの簡単なシグナル応答設定である。
    捕捉すべきシグナルと C 形式の関数を渡して ACE_Sig_Action オブジェクトを生成すればよい。
    想像できるようにシグナルハンドラをリアクタに登録する方法もあるが、今回は簡単な方法を選んだ。
 */

  ACE_Sig_Action sa ((ACE_SignalHandler) handler, SIGINT);

  ACE_DEBUG ((LM_DEBUG,
              "(%P|%t) starting up server logging daemon\n"));

  // SIGINT シグナルをハンドラが受けるまで、ロギングサービスを継続する。
  while (!finished)
    g_reactor->handle_events ();

  // これ以上の接続を受け入れないため、acceptor を閉じる。
  peer_acceptor.close();

  // リアクタに割り当てられたメモリを解放する。
  delete g_reactor;

  ACE_DEBUG ((LM_DEBUG,
              "(%P|%t) shutting down server logging daemon\n"));
  return 0;
}

#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
template class ACE_Acceptor <Logging_Handler, ACE_SOCK_ACCEPTOR>;
template class ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH>;
#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
#pragma instantiate ACE_Acceptor <Logging_Handler, ACE_SOCK_ACCEPTOR>
#pragma instantiate ACE_Svc_Handler<ACE_SOCK_STREAM, ACE_NULL_SYNCH>
#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */


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