プロジェクト

全般

プロフィール

バグ #2176

RTCがActive状態で終了(exit)する際のon_deactivate,on_finalizeの呼び出し順序の不整合

kuriharaほぼ13年前に追加. ほぼ13年前に更新.

ステータス:
終了
優先度:
通常
担当者:
-
対象バージョン:
-
開始日:
2011/06/29
期日:
進捗率:

100%

予定工数:

説明

株式会社セック 小田桐様からの報告

RTCがActive状態で終了(exit)する際、タイミングやRTCの周期の値に
よっては、on_deactivateが呼ばれない、もしくは、
on_finalizeが呼ばれた後にon_deactivateが呼ばれる場合があります。
原因は、RTObject_impl::exit内で、deactivate_componentを
呼び出した後、実際にRTCがInactive状態に遷移するのを
待っていないためです。

履歴

#1 kuriharaほぼ13年前に更新

  • プロジェクトOpenRTM-aist から OpenRTM-aist (C++) に変更

#2 n-andoほぼ13年前に更新

  • ステータス新規 から 終了 に変更
  • 進捗率0 から 100 に変更

PeriodicExecutionContext::deactivate_component(LightweightRTObject_ptr comp) 内で、

it->_sm.m_sm.goTo(INACTIVE_STATE);

のようにINACTIVE_STATEへの遷移を実行しているが、実行コンテキストは別スレッドで実行されているため実際にINACTIVEなっているかどうかを調べる必要がある。
以下のコードを追加

--- PeriodicExecutionContext.cpp    (revision 2191)
+++ PeriodicExecutionContext.cpp    (working copy)
@@ -374,14 +374,35 @@
     CompItr it;
     it = std::find_if(m_comps.begin(), m_comps.end(),
               find_comp(comp));
-    if (it == m_comps.end())
-      return RTC::BAD_PARAMETER;
-    
+    if (it == m_comps.end()) { return RTC::BAD_PARAMETER; }
     if (!(it->_sm.m_sm.isIn(ACTIVE_STATE)))
-      return RTC::PRECONDITION_NOT_MET;
+      {
+        return RTC::PRECONDITION_NOT_MET;
+      }

     it->_sm.m_sm.goTo(INACTIVE_STATE);
-    return RTC::RTC_OK;
+    int count(0);
+    const double usec_per_sec(1.0e6);
+    double sleeptime(10.0 * usec_per_sec / get_rate());
+    RTC_PARANOID(("Sleep time is %f [us]", sleeptime));
+    while (it->_sm.m_sm.isIn(ACTIVE_STATE))
+      {
+        RTC_TRACE(("Waiting to be the INACTIVE state"));
+        coil::usleep(sleeptime);
+        if (count > 1000)
+          {
+            RTC_ERROR(("The component is not responding."));
+            break;
+          }
+        ++count;
+      }
+    if (it->_sm.m_sm.isIn(INACTIVE_STATE))
+      {
+        RTC_TRACE(("The component has been properly deactivated."));
+        RTC::RTC_OK;
+      }
+    RTC_ERROR(("The component could not be deactivated."));
+    return RTC::RTC_ERROR;
 #else // ORB_IS_RTORB
     for (int i(0); i < (int)m_comps.size(); ++i)
       {
@@ -392,7 +413,29 @@
                 return RTC::PRECONDITION_NOT_MET;
               }
             m_comps.at(i)._sm.m_sm.goTo(INACTIVE_STATE);
-            return RTC::RTC_OK;
+            int count(0);
+            const double usec_per_sec(1.0e6);
+            double sleeptime(10.0 * usec_per_sec / get_rate());
+            RTC_PARANOID(("Sleep time is %f [us]", sleeptime));
+            while (m_comps.at(i)._sm.m_sm.isIn(ACTIVE_STATE))
+              {
+                RTC_TRACE(("Waiting to be the INACTIVE state"));
+                coil::usleep(sleeptime);
+                
+                if (count > 1000)
+                  {
+                    RTC_ERROR(("The component is not responding."));
+                    break;
+                  }
+                ++count;
+              }
+            if (m_comps.at(i)._sm.m_sm.isIn(INACTIVE_STATE))
+              {
+                RTC_TRACE(("The component has been properly deactivated."));
+                RTC::RTC_OK;
+              }
+            RTC_ERROR(("The component could not be deactivated."));
+            return RTC::RTC_ERROR;
           }
       }
     return RTC::BAD_PARAMETER;

他の形式にエクスポート: Atom PDF