[openrtm-users 00838] Re: SdoConfiguration のデストラクタ

Yasuaki Odagiri odagiri @ sec.co.jp
2009年 6月 16日 (火) 17:35:31 JST


安藤様

お世話になっております。
セック 小田桐です。

Configuration_implのデストラクタについてですが、コードを
見てみたところ、RTObject_implクラスのデストラクタで
メンバ変数m_pSdoConfigImplのdeleteを行っていないため、
現状のコードでは、Configuration_implのデストラクタが
呼ばれないと思います。

また、m_pSdoConfigImplをdeleteすると、別の問題も発生します。
RTObject_implはコンストラクタでConfiguration_var型である
メンバ変数にオブジェクトリファレンスを代入しています。

    m_pSdoConfig = m_pSdoConfigImpl->getObjRef();

Configuration_impl::getObjRef()は、Configuration_implが持つ
Configuration_varを_ptr型としてそのまま返しているだけですので、
オブジェクトリファレンスの参照回数がインクリメントされずに
m_pSdoConfigに代入されています。
そのため、RTObject_implのインスタンスを破棄した際、Configurationの
参照回数が余計にデクリメントされてしまいます。
m_pSdoConfigに代入する際はduplicateする必要があるかと思います。


ついでで恐縮ですが、その他、RTObject_implクラスで
気になった点も以下に報告しておきます。

・RTObject_implのコンストラクタでメンバ変数m_portAdminを
  初期化する際、引数で渡しているORBとPOAの
  オブジェクトリファレンスをduplicateしていません。
  PortAdminクラスは受け取ったORBとPOAをそのまま_var型に
  格納していますので、PortAdminのインスタンスが破棄されるとき、
  ORBとPOAの参照回数が余計にデクリメントされてしまいます。
  RTObject_implがORBとPOAをduplicateしてから渡す、もしくは、
  PortAdminクラスでORBとPOAをduplicateする必要があるかと思います。

・RTObject_implのコンストラクタで_ptr型のメンバ変数m_objrefに
  _this()でオブジェクトリファレンスを代入しています。
  _this()でもらったオブジェクトリファレンスはCORBA::releaseで
  解放する必要があると思いますので、m_objrefは_var型にすべきかと
  思います。

・RTObject_impl::initialize内の以下のコードに問題があります。
  RTObject.cppの317行目〜
  
    m_eclist.push_back(ec);
    ExecutionContextService_var ecv;
    ecv = ec->getObjRef();
    if (CORBA::is_nil(ecv)) return RTC::RTC_ERROR;

  PeriodicExecutionContext::getObjRefは、内部で保持している_var型の
  オブジェクトリファレンスを_ptr型としてそのまま返しています。
  そのため、ec->getObjRef()で取得したオブジェクトリファレンスは
  duplicateするか、_var型ではなく_ptr型に入れるべきだと思います。
  ここで_varに入れているため、スコープを抜けたときに余計に
  参照回数がデクリメントされています。
  そのため、ExecutionContextServiceのオブジェクトリファレンスを
  最後まで保持しているm_ecMineがRTObject_implのデストラクタで
  破棄されたときに問題が発生します。

・RTCを終了(exit)する際、on_shutdownがon_finalizeの後に
  呼ばれます。
  on_shutdownはon_finalizeの前に呼ばれるべきですが、
  順番が逆になっています。
  原因は、RTObject_impl::exit内で、m_ecMine[ic]->stop()と
  m_ecOther[ic]->stop()がコメントアウトされているためです。
  現状では、ECのstopは、on_finalizeの後に呼び出される
  RTObject_impl::finalizePorts()内で行われています。

・RTCがActive状態で終了(exit)すると、on_deactivateが
  呼ばれない場合があります。
  特に、周期の遅いRTCではほぼ確実に発生します。
  原因は、RTObject_impl::exit内で、deactivate_componentを
  呼び出した後、実際にRTCがInactive状態に遷移するのを
  待っていないためです。
  PeriodicExecutionContextのactivate_componentや
  deactivate_componentは、状態遷移のトリガーだけかけて、
  実際の状態遷移は周期実行されているスレッド上で行うという
  実装になっています。
  そのため、周期が遅い場合、deactivate_component呼び出し後、
  実際にInactive状態に遷移するまで時間がかかります。
  RTObject_impl::exitは、deactivate_component呼出し後、
  実際にInactive状態に遷移するのを待つべきではないかと
  思います。

長文失礼いたしました。

以上、よろしくお願いいたします。


On Thu, 4 Jun 2009 10:44:35 +0900
Ando Noriaki <n-ando @ aist.go.jp> wrote:

> 清水様
> 
> 安藤です
> 
> 
> > Configurationクラスは外部にexportして、
> > ユーザが自由に使ってもよいものではないのでしょうか。
> > もし、RTMの内部利用のみなら上記のような制約でも
> > 問題ないと思いますが、外部exportしていて、
> > ユーザにどう利用されるか分からないと仮定すると、
> > 「deleteする前に必ずdefaultPOAでdeactivate
> > しなければならない」という制約での
> > 実装は危険だと感じます。
> 
> SdoCondigurationクラスは、ConfigAdminクラスと一緒に使うように
> できているので、その辺を了解しているひとなら使えると思いますが、
> 今のところ他のユーザがそれらを単独で使うようには考慮していません。
> 
> Configurationは
> ・コンポーネント作成者からはあくまで、単なる変数へのアクセス
> ・外部からはSDOPackage::Configurationインターフェースからのアクセス
>  (しかも、SDOが保持しているという前提)
> という前提になっています。
> 
> > デストラクタの実装は私も非常に気を使うのですが、
> > このクラスの場合、defaultPOAでdeactivateさえ
> > しておけば、deleteされても問題ないと思います。
> > もし、deleteされる前にdeactivateされていた
> > 場合でも問題ないように、
> > deactivateの一連の処理をtry catch節で括っています。
> > CORBA仕様では、deactivate済みのオブジェクトのservant_to_id()
> > は例外を投げることになっているので、
> > そうしておけば常に安全にdeactivateされると
> > 考えたからです。
> >
> >
> >> そうですね、RTObjectのshutdown内でのdeactivateでManager
> > から
> >> もらったPOAでdeactivateをしているのでこれは問題になる
> > かもしれません。
> >>
> >> ところで、defaultでないPOAを使いたい場面とか、なにかあ
> > りますか。
> >> あるようなら、独自のServantBaseを実装してもよいのです
> > が。。。
> >
> > 現在のところは必要ありませんが、将来の拡張性や
> > メンテナンス性を考えての意見です。
> > 万一、ManagerのPOAがデフォルトでなくなった場合でも、
> > RTMのソース全体を見渡してPOAを逐一変更しなければ
> > ならないとなるとデバッグも大変なので、
> > そういう場合に備えてはどうでしょうか、ということです。
> 
> doilでは、いずれこの辺のコードはなくなってしまうか、自動生成する
> ともりだったので、汚いけど放置してました。
> どうするか今後検討させていただきます。
> -- 
> 安藤慶昭@独立行政法人産業技術総合研究所 研究員
>                   知能システム研究部門 統合知能研究グループ
>                   〒305-8568 茨城県つくば市梅園1-1-1 中央第2
>                   TEL: 029-861-5981 FAX: 029-862-6631
>                   n-ando @ aist.go.jp, n-ando @ ieee.org
> 

-----------------------------------------------------------
 株式会社セック 開発本部 第一開発部
   〒150-0031 東京都渋谷区桜丘町 22-14 NESビル
   TEL: 03-5458-7741    FAX : 03-5458-7726
   URL: http://www.sec.co.jp

 小田桐 康暁 (Yasuaki ODAGIRI)
   E-Mail: odagiri @ sec.co.jp
-----------------------------------------------------------




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