RtORBの開発メモ
このメモは、RtORBを再設計し、OpenRTM-aistのC言語実装を設計するためのメモである。また、現状のRtORBの動作の理解とOpenRTM-aistの基板となるC++インターフェースのバグフィックスの助けになると思われる。
RtORBとは?
RtORBは、事情通ロボットプロジェクトで培われた各モジュール構造を基本に実装されている。ただし、IDLコンパイラをORBit2で使用されてたものを使っているために、基本的なオブジェクト構造等は、ORBit2に準拠した形になっている。
これは、CORBAの標準C言語マッピングに準拠しているともいうこともできる。
CORBAコンポーネントの実行の基本的な流れ
RtORBは、CORBA3.0の仕様書を参照しながら実装しています。そのため、RtORBを使ったコンポーネントの開発は、次のようになる。
サーバー側(実装側)
- CORBA_ORB_init関数でORBを初期化。このときORB内には、オブジェク管理用のハッシュ表を作成している。
- CORBA_ORB_resolve_initialize_reference関数を実行し RootPOA獲得する。
- 呼び出されるオブジェクトの実装を生成する。
- NameServerに自分のオブジェクトリファレンスを登録する場合には、bindObjectToName関数で登録する。
- PortableServer_POA__get_the_POAManager関数でPortableServer_POAManagerを獲得する。
- PortableServer_POAManager_activate関数でPOAManagerを活性状態にする。
- CORBA_ORB_run関数でORBのイベントループを実行させる。
クライアント側(呼び出し側)
- CORBA_ORB_init関数でORBを初期化。このときORB内には、オブジェク管理用のハッシュ表を作成している。
- NameServerを使う場合には、CORBA_ORB_resolve_initial_reference関数で"NameService"のCosNamingContextを獲得する。
- CosNaming_NamingContext__resolve関数を呼び出し、NameServerに登録してある実装側のオブジェクトリファレンスを獲得する。
- NameServerを使わない場合には、CORBA_ORB_string_to_object関数を実行し、リファレンスに対応するオブジェクトリファアレンを生成する。
- 獲得したオブジェクトリファレンスを用いて、実装側のメソッドを呼び出す。
- 終了時には、CORBA_ORB_shutdown, CORBA_ORB_destroy を順に呼び出し、ORBを開放する。
上記からわかるように、一般的に実装と呼び出しを両方持つ場合には、ORBの生成、RootPOAの生成、公開オブジェクトのNameServerへの登録、POAManagerの活性化、ORBの実行をそれぞれのプログラムで行うことになります。
RtORBの基本的な構造
上記のCOBRAの一般的な動作からわかるように、CORBAオブジェクトには、外部からのメソッド呼び出しのための、通信経路とイベントループが必要になってくる。通信経路に関しては、仕様ではCORBAはGIOPが用いることになっていますが、ほとんどのCORBA実装はIIOPを使っています。IIOPは、TCP Socketを使ったメッセージ通信+GIOPのHeader+CDR化されたデータですので、Socketとそれをハンドリングするイベントループ、メージ内容を解釈するパーザがあれば、よいことになります。RtORBは、基本的にシングルスレッドで動作させることを念頭において実装しましたので、イベントループは、selectシステムコールを用いて複数のSocketポートの監視を行い、データ通信と関数呼び出しを実現しています。
これは、Threadを持たないOS上でも何とか動作させたいとの思いがあったためです。 (しかしながら、本来の分散オブジェクトの使い方をすると、簡単にデッドロックに陥ることがあるために、アプリケーションの実装には、十分な注意が必要となる。) これからわかるように、外部オブジェクトからのコールされる関数は、sleep等のwaitや呼出元への関数コールもしてはいけないという制限があります。 (この制限は、関数コールを別Threadで実行すれば、取り除くことができることはわかっている)

