2.6.2 TSCThreadを利用するサーバアプリケーションの例(C++)

TSCThreadを利用するサーバアプリケーションの処理の流れとコードの例を示します。斜体で示しているコードは,雛形クラスとして自動生成される部分です。太字で示しているコードは,同期型呼び出しのコードと異なる部分です。

サーバアプリケーションの作成時には,ユーザは,自動生成された雛形クラスABC_TSCimplにTSCユーザオブジェクトのコードを記述します。また,雛形クラスABC_TSCfactimplにTSCユーザオブジェクトファクトリのコードを記述します。さらに,TSCユーザスレッドとしてTSCThreadの派生クラスを記述し,TSCユーザスレッドファクトリとしてTSCThreadFactoryの派生クラスを記述します。

<この項の構成>
(1) TSCユーザオブジェクト(ABC_TSCimpl)とTSCユーザオブジェクトファクトリ(ABC_TSCfactimpl)のヘッダのコード
(2) TSCユーザオブジェクト(ABC_TSCimpl)とTSCユーザオブジェクトファクトリ(ABC_TSCfactimpl)のコード
(3) TSCユーザスレッド(UserTImpl)とTSCユーザスレッドファクトリ(UserFactImpl)のヘッダのコード
(4) TSCユーザスレッド(UserTImpl)とTSCユーザスレッドファクトリ(UserFactImpl)のコード
(5) サービス登録処理の流れ
(6) サービス登録処理のコード

(1) TSCユーザオブジェクト(ABC_TSCimpl)とTSCユーザオブジェクトファクトリ(ABC_TSCfactimpl)のヘッダのコード

//
// "ABCfile_TSC_t.hh"
//
#ifndef _ABCfile_TSC_T_HDR
#define _ABCfile_TSC_T_HDR

#include <tscobject.h>

#include "ABCfile_TSC_s.hh"

class ABC_TSCfactimpl : public TSCObjectFactory
{
public:
 // コンストラクタの引数の数および型を変更することもできます。
 ABC_TSCfactimpl();
 virtual ~ABC_TSCfactimpl();

 virtual TSCObject_ptr create();
 virtual void destroy(TSCObject_ptr tsc_object);

};

class ABC_TSCimpl : public ABC_TSCsk
{
private:

public:
 // コンストラクタの引数の数および型を変更することもできます。
 ABC_TSCimpl();
 ABC_TSCimpl(const char* _tpbroker_object_name);

 virtual ~ABC_TSCimpl();

 void call(const sampleOctetSeq& in_data,
                sampleOctetSeq*& out_data);

};

#endif  // _ABCfile_TSC_T_HDR

(2) TSCユーザオブジェクト(ABC_TSCimpl)とTSCユーザオブジェクトファクトリ(ABC_TSCfactimpl)のコード

//
// "ABCfile_TSC_t.cpp"
//
#include "ABCfile_TSC_t.hh"

#include "UserThread.h"

ABC_TSCfactimpl::ABC_TSCfactimpl()
{
 // Constructor of factory implementation.
 // Write user own code.
 // TSCユーザオブジェクトファクトリのコンストラクタのコードを記述
 // します。引数の数および型を変更することもできます。
}

ABC_TSCfactimpl::~ABC_TSCfactimpl()
{
 // Destructor of factory implementation.
 // Write user own code.
 // TSCユーザオブジェクトファクトリのデストラクタのコードを記述
 // します。
}

TSCObject_ptr
ABC_TSCfactimpl::create()
{
 // Method to create user object.
 // Write user own code.
 // サーバオブジェクトを生成するコードを記述します。
 // 必要に応じて変更してください。
 return new ABC_TSCimpl();
}

void
ABC_TSCfactimpl::destroy(TSCObject_ptr tsc_obj)
{
 // Method to destroy user object.
 // Write user own code.
 // ここに後処理のコードを記述します。
 // 必要に応じて変更してください。
 delete tsc_obj;
}

ABC_TSCimpl::ABC_TSCimpl()
{
 // Constructor of implementation.
 // Write user own code.
 // TSCユーザオブジェクトのコンストラクタのコードを記述します。
 // 引数の数および型を変更することもできます。
}

ABC_TSCimpl::ABC_TSCimpl(const char* _tpbroker_object_name)
      : ABC_TSCsk(_tpbroker_object_name)
{
 // Constructor of implementation.
 // Write user own code.
 // TSCユーザオブジェクトのコンストラクタのコードを記述します。
 // 引数の数および型を変更することもできます。
}

ABC_TSCimpl::~ABC_TSCimpl()
{
 // Destructor of implementation.
 // Write user own code.
 // TSCユーザオブジェクトのデストラクタのコードを記述します。
}

void ABC_TSCimpl::call(const sampleOctetSeq& in_data,
                           sampleOctetSeq*& out_data)
{
 // Operation "::ABC::call".
 // Write user own code.
 // ユーザメソッドのコードを記述します。

 // TSCユーザスレッドを取得
 // ここで取得したオブジェクトを消去してはいけません。
 TSCThread_ptr my_thr = this->_TSCThread();

 // ユーザクラスにキャスト
 // (仮想継承を使用している場合は,dynamic_castを利用して
 // ください)
 UserTImpl* my_thr_impl = (UserTImpl*)my_thr;

 // UserTImplのメソッドを呼び出し,値を取得します。
 CORBA::Long thr_value = my_thr_impl->getValue();

 // メソッドが呼ばれた回数を増加させます。
 // (このメソッドの処理は引数の値と無関係です)
 out_data = new sampleOctetSeq();
 out_data->length(0);
 printf("Call method in ABC_TSCimpl¥n");

}

(3) TSCユーザスレッド(UserTImpl)とTSCユーザスレッドファクトリ(UserFactImpl)のヘッダのコード

//
// "UserThread.h"
//

#include <tscobject.h>
#include <tscexcept.h>

class UserTImpl : public TSCThread
{
public:
 UserTImpl(CORBA::Long init_info);
 virtual ~UserTImpl();

 TSCInt getValue();

protected:
 //
 TSCInt m_value;
};


class UserTFactImpl : public TSCThreadFactory
{
public:
 UserTFactImpl();
 virtual ~UserTFactImpl();

 virtual TSCThread_ptr create();

 virtual void destroy(TSCThread_ptr tsc_object);
};

(4) TSCユーザスレッド(UserTImpl)とTSCユーザスレッドファクトリ(UserFactImpl)のコード

//
// "UserThread.cpp
//
#include <tscobject.h>
#include <tscexcept.h>

#include "UserThread.h"

UserTImpl::UserTImpl(CORBA::Long init_value)
 : m_value(init_value)
{}

UserTImpl::~UserTImpl()
{}

//
//ユーザ定義のメソッド
//
TSCInt
UserTImpl::getValue()
{
 return m_value;
}

UserTFactImpl::UserTFactImpl()
{}

UserTFactImpl::~UserTFactImpl()
{}

TSCThread_ptr
UserTFactImpl::create()
{
 //TSCユーザスレッドを生成します。
 TSCThread_ptr usr_thr = new UserTImpl(222);
 return usr_thr;
}

void
UserTFactImpl::destroy(TSCThread_ptr tsc_thr)
{
 //TSCユーザスレッドを削除します。
 delete tsc_thr;
}

(5) サービス登録処理の流れ

  1. TPBrokerの初期化処理
  2. TPBroker OTMの初期化処理
  3. TSCデーモンへの接続
  4. TSCユーザオブジェクトファクトリ,TSCユーザアクセプタの生成(new),および各種設定
  5. TSCユーザスレッドファクトリの生成(new)および各種設定
  6. TSCルートアクセプタの生成および各種設定
  7. TSCルートアクセプタの活性化
  8. 実行制御の受け渡し
  9. TSCルートアクセプタの非活性化
  10. TSCルートアクセプタの削除
  11. TSCユーザオブジェクトファクトリおよびTSCユーザアクセプタの削除(delete)
  12. TSCデーモンへの接続解放
  13. TPBroker OTMの終了処理

(6) サービス登録処理のコード

//
//  "Server.cpp"
//
#include <stdio.h>
#include <iostream.h>

#include <tscadm.h>
#include <tscobject.h>
#include <tscexcept.h>

#include "ABCfile_TSC_t.hh"
#include "UserThread.h"

#define ERR_FORMAT
   "EC=%d,DC=%d,PC=%d,CS=%d,MC1=%d,MC2=%d,MC3=%d,MC4=%d¥n"

int main(int argc, char** argv)
{

 ////////
 // 1, TPBrokerの初期化処理
 ////////

 CORBA::ORB_ptr orb = 0;
 try
 {
   // ORBの初期化
   orb = CORBA::ORB_init(argc, argv);
 }
 catch(CORBA::SystemException& se)
 {
   // 例外処理
   cerr << se << endl;
   exit(1);
 }

 ////////
 // 2, TPBroker OTMの初期化処理
 ////////

 try
 {
   // TSCの初期化
   TSCAdm::initServer(argc, argv, orb);
 }
 catch(TSCSystemException& se)
 {
   // 例外処理
   fprintf(stderr, ERR_FORMAT,
      se.getErrorCode(), se.getDetailCode(),
      se.getPlaceCode(), se.getCompletionStatus(),
      se.getMaintenanceCode1(), se.getMaintenanceCode2(),
      se.getMaintenanceCode3(), se.getMaintenanceCode4());
   exit(1);
 }

 ////////
 // 3, TSCデーモンへの接続
 ////////

 TSCDomain_ptr tsc_domain = 0;

 try
 {
   tsc_domain = new TSCDomain(0, 0);
 }
 catch(TSCSystemException& se)
 {
   // 例外処理
   fprintf(stderr, ERR_FORMAT,
      se.getErrorCode(), se.getDetailCode(),
      se.getPlaceCode(), se.getCompletionStatus(),
      se.getMaintenanceCode1(), se.getMaintenanceCode2(),
      se.getMaintenanceCode3(), se.getMaintenanceCode4());
   try
   {
     TSCAdm::endServer();
   }
   catch(TSCSystemException& se)
   {
     exit(1);
   }
   exit(1);
 }

 TSCServer_ptr tsc_server = 0;

 try
 {
   // TSCデーモンの参照オブジェクトを取得
   tsc_server = TSCAdm::getTSCServer(tsc_domain);
 }
 catch(TSCSystemException& se)
 {
   // 例外処理
   fprintf(stderr, ERR_FORMAT,
      se.getErrorCode(), se.getDetailCode(),
      se.getPlaceCode(), se.getCompletionStatus(),
      se.getMaintenanceCode1(), se.getMaintenanceCode2(),
      se.getMaintenanceCode3(), se.getMaintenanceCode4());
   try
   {
     TSCAdm::endServer();
   }
   catch(TSCSystemException& se)
   {
     exit(1);
   }
   exit(1);
 }

 ////////
 // 4, TSCユーザオブジェクトファクトリ,TSCユーザアクセプタ(new),
 //    および各種設定
 ////////

 // ABC_TSCfactimplの生成
 TSCObjectFactory_ptr my_obj_fact = new ABC_TSCfactimpl();

 // TSCAcceptorの生成
 TSCAcceptor_ptr my_acpt = 0;

 try
 {
   my_acpt = new ABC_TSCacpt(my_obj_fact);
 }
 catch(TSCSystemException& se)
 {
   // 例外処理
   fprintf(stderr, ERR_FORMAT,
      se.getErrorCode(), se.getDetailCode(),
      se.getPlaceCode(), se.getCompletionStatus(),
      se.getMaintenanceCode1(), se.getMaintenanceCode2(),
      se.getMaintenanceCode3(), se.getMaintenanceCode4());
   try
   {
     delete my_obj_fact;
     TSCAdm::releaseTSCServer(tsc_server);
     TSCAdm::endServer();
     exit(1);
   }
   catch(TSCSystemException& se)
   {
     exit(1);
   }
   exit(1);
 }

 //////
 // 5, TSCユーザスレッドファクトリの生成(new)および各種設定
 //////
 TSCThreadFactory_ptr  my_thr_fact = new UserTFactImpl();

 ////////
 // 6, TSCルートアクセプタの生成および各種設定
 ////////

 // TSCRootAcceptorの生成
 TSCRootAcceptor_ptr my_rt_acpt = 0;

 try
 {
  my_rt_acpt = TSCRootAcceptor::create(tsc_server,
                                        my_thr_fact);
 }
 catch(TSCSystemException& se)
 {
   // 例外処理
   fprintf(stderr, ERR_FORMAT,
      se.getErrorCode(), se.getDetailCode(),
      se.getPlaceCode(), se.getCompletionStatus(),
      se.getMaintenanceCode1(), se.getMaintenanceCode2(),
      se.getMaintenanceCode3(), se.getMaintenanceCode4());
   try
   {
     delete my_acpt;
     delete my_obj_fact;
     TSCAdm::releaseTSCServer(tsc_server);
     TSCAdm::endServer();
     exit(1);
   }
   catch(TSCSystemException& se)
   {
     exit(1);
   }
   exit(1);
 }

 try
 {
   // TSCRootAcceptorへの登録
   my_rt_acpt->registerAcceptor(my_acpt);

   // TSCRootAcceptorのパラレルカウント指定もできます。
   // デフォルト値は1
   // オプション引数でデフォルト値を変更することもできます。
   // my_rt_acpt->setParallelCount(5);
 }
 catch(TSCSystemException& se)
 {
   // 例外処理
   fprintf(stderr, ERR_FORMAT,
      se.getErrorCode(), se.getDetailCode(),
      se.getPlaceCode(), se.getCompletionStatus(),
      se.getMaintenanceCode1(), se.getMaintenanceCode2(),
      se.getMaintenanceCode3(), se.getMaintenanceCode4());
   try
   {
     TSCRootAcceptor::destroy(my_rt_acpt);
     delete my_acpt;
     delete my_obj_fact;
     TSCAdm::releaseTSCServer(tsc_server);
     TSCAdm::endServer();
     exit(1);
   }
   catch(TSCSystemException& se)
   {
     exit(1);
   }
   exit(1);
 }

 ////////
 // 7, TSCルートアクセプタの活性化
 ////////

 try
 {
   // オブジェクトの活性化
   my_rt_acpt->activate("serviceX");
 }
 catch(TSCSystemException& se)
 {
   // 例外処理
   fprintf(stderr, ERR_FORMAT,
      se.getErrorCode(), se.getDetailCode(),
      se.getPlaceCode(), se.getCompletionStatus(),
      se.getMaintenanceCode1(), se.getMaintenanceCode2(),
      se.getMaintenanceCode3(), se.getMaintenanceCode4());
   try
   {
     my_rt_acpt->deactivate();
     TSCRootAcceptor::destroy(my_rt_acpt);
     delete my_acpt;
     delete my_obj_fact;
     TSCAdm::releaseTSCServer(tsc_server);
     TSCAdm::endServer();
   }
   catch(TSCSystemException& se)
   {
     exit(1);
   }
   exit(1);
 }

 ////////
 // 8, 実行制御の受け渡し
 ////////

 try
 {
   TSCAdm::serverMainloop();
 }
 catch(TSCSystemException& se)
 {
   // 例外処理
   fprintf(stderr, ERR_FORMAT,
     se.getErrorCode(), se.getDetailCode(),
     se.getPlaceCode(), se.getCompletionStatus(),
     se.getMaintenanceCode1(), se.getMaintenanceCode2(),
     se.getMaintenanceCode3(), se.getMaintenanceCode4());
   try
   {
     my_rt_acpt->deactivate();
     TSCRootAcceptor::destroy(my_rt_acpt);
     delete my_acpt;
     delete my_obj_fact;
     TSCAdm::releaseTSCServer(tsc_server);
     TSCAdm::endServer();
   }
   catch(TSCSystemException& se)
   {
     exit(1);
   }
   exit(1);
 }

 ////////
 // 9, TSCルートアクセプタの非活性化
 ////////

 try
 {
   // オブジェクトの非活性化
   my_rt_acpt->deactivate();
 }
 catch(TSCSystemException& se)
 {
   // 例外処理
   fprintf(stderr, ERR_FORMAT,
      se.getErrorCode(), se.getDetailCode(),
      se.getPlaceCode(), se.getCompletionStatus(),
      se.getMaintenanceCode1(), se.getMaintenanceCode2(),
      se.getMaintenanceCode3(), se.getMaintenanceCode4());
   try
   {
     TSCRootAcceptor::destroy(my_rt_acpt);
     delete my_acpt;
     delete my_obj_fact;
     TSCAdm::releaseTSCServer(tsc_server);
     TSCAdm::endServer();
   }
   catch(TSCSystemException& se)
   {
     exit(1);
   }
   exit(1);
 }

 ////////
 // 10, TSCルートアクセプタの削除
 ////////

 TSCRootAcceptor::destroy(my_rt_acpt);

 ////////
 // 11, TSCユーザオブジェクトファクトリおよびTSCユーザアクセプタの
 //     削除(delete)
 ////////

 delete my_acpt;
 delete my_obj_fact;

 ////////
 // 12, TSCデーモンへの接続解放
 ////////

 try
 {
   TSCAdm::releaseTSCServer(tsc_server);
 }
 catch(TSCSystemException& se)
 {
   // 例外処理
   fprintf(stderr, ERR_FORMAT,
      se.getErrorCode(), se.getDetailCode(),
      se.getPlaceCode(), se.getCompletionStatus(),
      se.getMaintenanceCode1(), se.getMaintenanceCode2(),
      se.getMaintenanceCode3(), se.getMaintenanceCode4());
   try
   {
     TSCAdm::endServer();
   }
   catch(TSCSystemException& se)
   {
     exit(1);
   }
   exit(1);
 }

 delete tsc_domain;

 ////////
 // 13, TPBroker OTMの終了処理
 ////////

 try
 {
   TSCAdm::endServer();
 }
 catch(TSCSystemException& se)
 {
   // 例外処理
   fprintf(stderr, ERR_FORMAT,
      se.getErrorCode(), se.getDetailCode(),
      se.getPlaceCode(), se.getCompletionStatus(),
      se.getMaintenanceCode1(), se.getMaintenanceCode2(),
      se.getMaintenanceCode3(), se.getMaintenanceCode4());
   exit(1);
 }

 exit(0);

};