[openrtm-users 01483] Re: rtc_handle for OpenrtM-aist-1.0.0 (ほぼ完成か?)

原 功 isao-hara @ aist.go.jp
2010年 11月 11日 (木) 09:39:06 JST


安藤さん:

原@産総研です。そちらは、もう深夜では?

On 2010/11/11, at 9:20, Ando Noriaki wrote:
> 
> 上の文章の意味は、下のDosygenのドキュメント上の(OMG RTCの方でなく、私が決めた)仕様に従って
> connect()を呼び出している限りは、その仕様に従ってメモリリークテストをしており、
> リークは検出されなかった、という事実を述べただけです。
了解しました。

> 
> Dosygenで書かれた仕様で想定されている以外の方法で(例えば変なConnectorProfileを
> connect()に与えるなど)呼び出された場合は、リークするかもしれませんし、
> 最悪クラッシュするかもしれません。引数に与えられたConnectorProfileに不整合が
> あった場合、極力検出してエラーにするなど対処はしているつもりですが、
> それにも限界はあるので、仕様としてDoxygenで明記し呼び出す側に対処をお願いしています。
> これは、通常許されることだと思います。
それはそうなのですが、通常許されても、安全なコードを書くためのガイドラインが必要では?
OpenRTM-aistを使っていれば、安全なコンポーネントができるとうことをいうためには、
ガイドラインが必須だと思います。

> 
> すみません、これについてはCORBAの仕様をそこまで深く知らないのでわかりません。
> ORBが非スレッドモデルの場合に、同一ORB上のオブジェクトをたがいに呼び出して、
> デッドロックに陥るという意味でしょうか?
> 
その通りです。disconnect()では、しっかりデッドロックが起こっていました。

>>> もう少し詳細な仕様については以下のようになっています。
>>> http://www.openrtm.org/OpenRTM-aist/documents/current/cxx/classreference_ja/classRTC_1_1PortBase.html#a139d07d2e94f7e793aedf4aa24b92462
>>> 
>> ここに、”connect() および途中の notify_connect() が ConnectorProfile::{name, ports} を変更することはない。” と書いてありますが、
>> notify_connect()をカスケード呼び出しするときには、ConnectorProfile::{name, ports} が変更されて呼び出されます。(IORが追加されます)
>> ここが、私がはまったところです。
> 
> 変更されるのは ConnectorProfile::properties ではないですか?
その通りです。

> ConnectorProfileのnameもportもいじらないはずですが、
> nameはいじったところであまり得以上はないですが、portは途中で
> 変更されると、カスケード呼び出しの前提が崩れてしまうので、
> 絶対に変更してはいけないはずです。
私が見たところ、nameとportは変更されていませんでした。

> もしいじっている箇所があるとしたらそれはバグになります。
> どの部分かお分かりでしたら教えていただけないでしょうか?
> 
> ちなみに、notify_connect()のカスケード呼び出しを行う場合、
> プロバイダの参照をすべてのportに周知させるために、行きのnotify_connect()で
> ConnectorProfile::propertiesにインターフェース名とIOR文字列のペアと、
> インターフェース名とAny型に入れたCORBA Objectの2通りで格納しています。
> さらに、戻りの呼び出しではコンシューマが自分の取得すべきIORを
> ConnectorProfile::propertiesの中から探し出し、プレースホルダに格納します。
> 一応、こういう流れになっています。
これは、ソースコードを追っていてわかりました。ところで、インターフェース名とIORの文字列は、
同じものですので、どちらか必要ないのでは?

> 
> その通りです。なので、ツール側で適切なConnectorProfileを作ってもらえるように、
> Doxygenの方でconnect()関数の呼び出し方の決まりをこのように書いています。
そうであれば、SystemEditorは、実装を変更して欲しいものです。ConnectorProfileの起点が
最初にポイントしたコンポーネントになっています。

> で末廣先生のケースでは、connector_idが同じ場合についてDoxygenで、
> 
>  ConnectorProfile::connector_id はすべての接続に対して一意な ID (通常はUUID) が格納される。
>  UUIDの設定は connect() 関数内で行 われるので、呼び出し側は空文字を設定する。
>  既存の接続と同じUUIDを 設定し connect() を呼び出した場合には PRECONDITION_NOT_MET
>  エラー を返す。ただし、将来の拡張で既存の接続プロファイルを更新するため に既存の UUID を
>  設定して呼び出す使用法が用いられる可能性がある。
> 
> こう書かれているように、既存の接続と同じUUIDを設定してconnect()を呼び出してしまったため
> 問題が起こったのだと思います。(将来を先取りしたとも言えますが、実装が追いついてません。。。)
なるほど、UUIDを使っていたのですね。name-UUIDのマップがあれば、nameで指定すればよいと思いますが。
> 
> http://openrtp.jp/openrtm/svn/OpenRTM-aist/branches/RELENG_1_0/OpenRTM-aist/src/lib/rtm/PortBase.cpp
> 
> 上記のように、実際 connect() に与えられるConnectorProfile::connector_id は空文字が前提ですが、
> 実装上は、connect()内で
> 
> ・空文字->UUIDを生成
> ・既存のID->PRECONDITION_NOT_METエラーを返しログにもその旨出力
> ・それ以外の文字列->何もしないで通過
>  (これはDoxygen上の仕様には明記されておらず、UUIDかどうかのチェックもしていないので
>  まずいといえばまずいが、他のConnectorProfileと区別できる一意なキーであればよいので、
>  致命的なエラーにはならない。OMG RTCではconnector_idがUUIDとは言ってないし。。。)
> 
> というように3つのケースに分けて処理をしています。
> ちなみに、ConnectorProfile::connector_id に何もセットしないで呼び出す、
> という場合もありますが、この場合CORBAの呼び出し自体がエラーになります。
> 
> 以上のように、処理の漏れを少なくするようには実装していて、それでも
> 不十分なところについては、ドキュメント側で制約を設けることにより対処しています。
> それでも不十分な個所は沢山あると思いますので、問題点を見つけられた場合は
> お知らせいただければ幸いです。>みなさま
これも、ソースコードを読んでいくうちに分かっていましたが、OpenRTMの移植に必要な情報、RTCを作成
するときの注意点などが、Doxygenの文章で散在しているので、ここを読めばという、まとまった文書がないと
なかなか難しいと思います。
検索すればと言われてもキーがわかりませんし、Doxygenの文書のところにキーワードがあると思いますが、
どのようなキーワードかがREADMEなどのトップ文書で明示的に書いていないでわかりにくい原因になって
いると思います。
文書作成は、使う側の視点での作成が重要です。私の個人的な印象ですが、文書が十分あるが、まとまっていないので
探しにくいです。

------------------------------------------------------------
産業技術総合研究所   知能システム研究部門 インタラクションモデリングG
主任研究員 原  功 <Isao-Hara @ aist.go.jp>
Isao HARA, Senior Researcher, ISRI, ,AIST,Japan
TEL: +81-29-861-5973       FAX: +81-29-862-6631









openrtm-users メーリングリストの案内