[openrtm-users 00799] SdoConfiguration のデストラクタ

6 個の投稿 / 0 new
最終投稿
root
オフライン
Last seen: 1日 8時間 前
登録日: 2009-06-23 14:31
[openrtm-users 00799] SdoConfiguration のデストラクタ

OpenRTM-aist開発者の皆様

SdoConfigurationのデストラクタ、
SDOPackage::~Configuration_impl();
の実装がまずいと思います。

このクラスはCORBAサーバント実装なので、
コンストラクタで、
this->_this();
とimplicit activationしています。
したがって、デストラクタでdeactivation
をしなければ安全でないと思います。
このクラスをnewしてそのままdeleteされる
可能性を考えて実装すべきと考えます。

よって、以下のようなデストラクタの実装が
必要ではないでしょうか。
----------
try{
PortableServer::POA_var poa = this->_default_POA();
PortableServer::ObjectId* id =
poa->servant_to_id(this);
poa->deactivate_object(*id);
}catch(...){
}
----------

P.S. ところで、このクラスではdefaultPOAを使っていますが

ManagerのPOAと一致させなくても大丈夫なのでしょうか?
現在のところは、ManagerのPOAもdefaultPOAなのでよいですが

もし将来的にManagerのPOAがdefaultPOAでなくなったときに、
何らかの問題が起きるのでは?と感じます。

静岡大 清水

未定義
root
オフライン
Last seen: 1日 8時間 前
登録日: 2009-06-23 14:31
[openrtm-users 00803] SdoConfiguration のデストラクタ

安藤です

> OpenRTM-aist開発者の皆様
>
> SdoConfigurationのデストラクタ、
> SDOPackage::~Configuration_impl();
> の実装がまずいと思います。
>
> このクラスはCORBAサーバント実装なので、
> コンストラクタで、
> this->_this();
> とimplicit activationしています。
> したがって、デストラクタでdeactivation
> をしなければ安全でないと思います。
> このクラスをnewしてそのままdeleteされる
> 可能性を考えて実装すべきと考えます。

SdoConfigurationのdeactivateはRTObjectのshutdownの中で行っています。
SdoConfigurationの寿命はRTObjectの寿命以下なので、
とりあえずこれでも問題ないと思います。
コンストラクタの中で、activateしているので、デストラクタの中で
deactivateするのが筋かとは思いますが。

> よって、以下のようなデストラクタの実装が
> 必要ではないでしょうか。
> ----------
> try{
> PortableServer::POA_var poa = this->_default_POA();
> PortableServer::ObjectId* id =
> poa->servant_to_id(this);
> poa->deactivate_object(*id);
> }catch(...){
> }
> ----------
>
> P.S. ところで、このクラスではdefaultPOAを使っていますが
> 、
> ManagerのPOAと一致させなくても大丈夫なのでしょうか?
> 現在のところは、ManagerのPOAもdefaultPOAなのでよいですが
> 、
> もし将来的にManagerのPOAがdefaultPOAでなくなったときに、
> 何らかの問題が起きるのでは?と感じます。

そうですね、RTObjectのshutdown内でのdeactivateでManagerから
もらったPOAでdeactivateをしているのでこれは問題になるかもしれません。

ところで、defaultでないPOAを使いたい場面とか、なにかありますか。
あるようなら、独自のServantBaseを実装してもよいのですが。。。

root
オフライン
Last seen: 1日 8時間 前
登録日: 2009-06-23 14:31
[openrtm-users 00805] SdoConfiguration のデストラクタ

安藤様

> SdoConfigurationのdeactivateはRTObjectのshutdownの中で
行っています。
> SdoConfigurationの寿命はRTObjectの寿命以下なので、
> とりあえずこれでも問題ないと思います。
> コンストラクタの中で、activateしているので、デストラク
タの中で
> deactivateするのが筋かとは思いますが。

Configurationクラスは外部にexportして、
ユーザが自由に使ってもよいものではないのでしょうか。
もし、RTMの内部利用のみなら上記のような制約でも
問題ないと思いますが、外部exportしていて、
ユーザにどう利用されるか分からないと仮定すると、
「deleteする前に必ずdefaultPOAでdeactivate
しなければならない」という制約での
実装は危険だと感じます。

デストラクタの実装は私も非常に気を使うのですが、
このクラスの場合、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を逐一変更しなければ
ならないとなるとデバッグも大変なので、
そういう場合に備えてはどうでしょうか、ということです。

清水

root
オフライン
Last seen: 1日 8時間 前
登録日: 2009-06-23 14:31
[openrtm-users 00818] SdoConfiguration のデストラクタ

清水様

安藤です

> 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では、いずれこの辺のコードはなくなってしまうか、自動生成する
ともりだったので、汚いけど放置してました。
どうするか今後検討させていただきます。

root
オフライン
Last seen: 1日 8時間 前
登録日: 2009-06-23 14:31
[openrtm-users 00838] SdoConfiguration のデストラクタ

安藤様

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

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 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では、いずれこの辺のコードはなくなってしまうか、自動生成する
> ともりだったので、汚いけど放置してました。
> どうするか今後検討させていただきます。

root
オフライン
Last seen: 1日 8時間 前
登録日: 2009-06-23 14:31
[openrtm-users 00864] SdoConfiguration のデストラクタ

小田桐さま

安藤です

お返事が遅くなり申し訳ありません。
また詳細な調査ありがとうございます。
こちらでも_var型_ptr型の扱いに関しては1.0開発時に詳細に調査し、
リークがないように修正いたしました。故あってRC1には反映させませんでしたが、
次(RC2?)では修正されたコードに置き換わる予定です。

後半の、on_shutdownとon_finalizeの呼び出し順、on_deactivateが
呼ばれない問題などについては調査して修正したいと思います。

ありがとうございました。

2009/06/16 17:35 に Yasuaki Odagiri さんは書きました:
> 安藤様
>
> お世話になっております。
> セック 小田桐です。
>
> 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 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では、いずれこの辺のコードはなくなってしまうか、自動生成する
>> ともりだったので、汚いけど放置してました。
>> どうするか今後検討させていただきます。

コメントを投稿するにはログインまたはユーザー登録を行ってください

ダウンロード

最新バージョン : 2.0.1-RELESE

統計

Webサイト統計
ユーザ数:2209
プロジェクト統計
RTコンポーネント307
RTミドルウエア35
ツール22
文書・仕様書2

Choreonoid

モーションエディタ/シミュレータ

OpenHRP3

動力学シミュレータ

OpenRTP

統合開発プラットフォーム

産総研RTC集

産総研が提供するRTC集

TORK

東京オープンソースロボティクス協会

DAQ-Middleware

ネットワーク分散環境でデータ収集用ソフトウェアを容易に構築するためのソフトウェア・フレームワーク