[openrtm-commit:00766] r527 - in branches/work/OpenRTM-aist-Python/OpenRTM_aist: . test

openrtm @ openrtm.org openrtm @ openrtm.org
2012年 3月 13日 (火) 16:43:23 JST


Author: kurihara
Date: 2012-03-13 16:43:23 +0900 (Tue, 13 Mar 2012)
New Revision: 527

Modified:
   branches/work/OpenRTM-aist-Python/OpenRTM_aist/PeriodicExecutionContext.py
   branches/work/OpenRTM-aist-Python/OpenRTM_aist/test/test_PeriodicExecutionContext.py
Log:
[incompatible] ExecutionContextBase's super classes have been moved to PeriodicExecutionContext class.  refs #2323

[incomaptible API] Now ExecutionContextProfile management has been moved to ExecutionContextBase. getObjRef() is also moved to ExecutionContextBase.
[incompatible behavior] Now onExecute and onStateUpdate execution behavior has been changed when two or more RTCs attached to the EC. refs #2320
  Old: A::onExecute, A::onStateUpdate, B::onExecute, B::onStateUpdate
  New: A::onExecute, B::onExecute, A::onStateUpdate, B::onStateUpdate

Modified: branches/work/OpenRTM-aist-Python/OpenRTM_aist/PeriodicExecutionContext.py
===================================================================
--- branches/work/OpenRTM-aist-Python/OpenRTM_aist/PeriodicExecutionContext.py	2012-03-13 07:15:16 UTC (rev 526)
+++ branches/work/OpenRTM-aist-Python/OpenRTM_aist/PeriodicExecutionContext.py	2012-03-13 07:43:23 UTC (rev 527)
@@ -22,7 +22,7 @@
 
 import OpenRTM_aist
 import OpenRTM
-import RTC
+import RTC, RTC__POA
 
 DEFAULT_PERIOD = 0.000001
 
@@ -40,383 +40,59 @@
 # @brief PeriodicExecutionContext class
 # @endif
 class PeriodicExecutionContext(OpenRTM_aist.ExecutionContextBase,
+                               RTC__POA.ExecutionContextService,
                                OpenRTM_aist.Task):
   """
   """
 
-
-
   ##
   # @if jp
-  # @class DFP
-  # @brief DFP クラス
-  #
-  # 参加者リストに登録された DataFlowParticipant の関数を起動するための
-  # 内部クラス。
-  #
-  # @param Object 管理対象コンポーネントの型
-  #
-  # @else
-  #
-  # @endif
-  class DFP:
-    """
-    """
-
-    ##
-    # @if jp
-    # @brief デフォルトコンストラクタ
-    #
-    # デフォルトコンストラクタ
-    #
-    # @param self
-    # @param obj 管理対象コンポーネント
-    # @param id_ 所属する ExecutionContext のID
-    #
-    # @else
-    # @brief Constructor
-    # @endif
-    def __init__(self, obj, id_):
-      self._obj = obj
-      self._active = True
-      self.ec_id = id_
-      self._sm = OpenRTM_aist.StateMachine(4)
-      self._sm.setListener(self)
-      self._sm.setEntryAction (RTC.ACTIVE_STATE,
-                               self.on_activated)
-      self._sm.setDoAction    (RTC.ACTIVE_STATE,
-                               self.on_execute)
-      self._sm.setPostDoAction(RTC.ACTIVE_STATE,
-                               self.on_state_update)
-      self._sm.setExitAction  (RTC.ACTIVE_STATE,
-                               self.on_deactivated)
-      self._sm.setEntryAction (RTC.ERROR_STATE,
-                               self.on_aborting)
-      self._sm.setDoAction    (RTC.ERROR_STATE,
-                               self.on_error)
-      self._sm.setExitAction  (RTC.ERROR_STATE,
-                               self.on_reset)
-      st = OpenRTM_aist.StateHolder()
-      st.prev = RTC.INACTIVE_STATE
-      st.curr = RTC.INACTIVE_STATE
-      st.next = RTC.INACTIVE_STATE
-      self._sm.setStartState(st)
-      self._sm.goTo(RTC.INACTIVE_STATE)
-
-
-    ##
-    # @if jp
-    # @brief ExecutionContext 実行開始時に呼ばれる関数
-    #
-    # 参加している ExecutionContext が実行を開始する時(Running状態へ遷移時)
-    # に、管理対象コンポーネントの on_startup を呼びだす。
-    #
-    # @param self
-    #
-    # @else
-    #
-    # @brief
-    #
-    # @endif
-    def on_startup(self):
-      return self._obj.on_startup(self.ec_id)
-
-
-    ##
-    # @if jp
-    # @brief ExecutionContext 停止時に呼ばれる関数
-    #
-    # 参加している ExecutionContext が実行を停止する時(Stopped状態へ遷移時)
-    # に、管理対象コンポーネントの on_shutdown を呼びだす。
-    #
-    # @param self
-    #
-    # @else
-    #
-    # @endif
-    def on_shutdown(self):
-      return self._obj.on_shutdown(self.ec_id)
-
-
-    ##
-    # @if jp
-    # @brief RTコンポーネントがアクティブ化された時に呼ばれる関数
-    #
-    # 管理対象のRTコンポーネントがアクティブ化された時(Active状態へ遷移時)
-    # に、管理対象コンポーネントの on_activated を呼びだす。
-    # 管理対象コンポーネントのアクティブ化が失敗した場合には、ステートマシン
-    # を Error 状態に遷移させる。
-    #
-    # @param self
-    # @param st 対象RTコンポーネントの現在の状態
-    #
-    # @else
-    #
-    # @endif
-    def on_activated(self, st):
-      if self._obj.on_activated(self.ec_id) != RTC.RTC_OK:
-        self._sm.goTo(RTC.ERROR_STATE)
-        return
-      return
-
-
-    ##
-    # @if jp
-    # @brief RTコンポーネントが非アクティブ化された時に呼ばれる関数
-    #
-    # 管理対象のRTコンポーネントが非アクティブ化された時
-    # (Deactive状態へ遷移時)に、管理対象コンポーネントの on_deactivated を
-    # 呼びだす。
-    #
-    # @param self
-    # @param st 対象RTコンポーネントの現在の状態
-    #
-    # @else
-    #
-    # @endif
-    def on_deactivated(self, st):
-      self._obj.on_deactivated(self.ec_id)
-
-
-    ##
-    # @if jp
-    # @brief RTコンポーネントでエラーが発生した時に呼ばれる関数
-    #
-    # 管理対象のRTコンポーネントにエラーが発生した時(Error状態へ遷移時)
-    # に管理対象コンポーネントの on_aborting を呼びだす。
-    #
-    # @param self
-    # @param st 対象RTコンポーネントの現在の状態
-    #
-    # @else
-    #
-    # @brief
-    #
-    # @endif
-    def on_aborting(self, st):
-      self._obj.on_aborting(self.ec_id)
-
-
-    ##
-    # @if jp
-    # @brief RTコンポーネントがエラー状態の時に呼ばれる関数
-    #
-    # 管理対象のRTコンポーネントがエラー状態にいる間、 
-    # 管理対象コンポーネントの on_error を定期的に呼びだす。
-    #
-    # @param self
-    # @param st 対象RTコンポーネントの現在の状態
-    #
-    # @else
-    #
-    # @brief
-    #
-    # @endif
-    def on_error(self, st):
-      self._obj.on_error(self.ec_id)
-
-
-    ##
-    # @if jp
-    # @brief RTコンポーネントをリセットする時に呼ばれる関数
-    #
-    # 管理対象のRTコンポーネントをリセットする際に、管理対象コンポーネント
-    # の on_reset を呼びだす。
-    #
-    # @param self
-    # @param st 対象RTコンポーネントの現在の状態
-    #
-    # @else
-    #
-    # @endif
-    def on_reset(self, st):
-      if self._obj.on_reset(self.ec_id) != RTC.RTC_OK:
-        self._sm.goTo(RTC.ERROR_STATE)
-        return
-      return
-
-
-    ##
-    # @if jp
-    # @brief RTコンポーネント実行時に定期的に呼ばれる関数
-    #
-    # 管理対象のRTコンポーネントが Active 状態であるとともに、
-    # ExecutionContext が Running 状態の場合に、設定された動作周期で定期的に
-    # 管理対象コンポーネントの on_execute を呼びだす。
-    # 関数の実行に失敗した場合(返値が RTC_OK 以外)、管理対象コンポーネントの
-    # 状態を Error 状態に遷移させる。
-    #
-    # @param self
-    # @param st 対象RTコンポーネントの現在の状態
-    #
-    # @else
-    #
-    # @endif
-    def on_execute(self, st):
-      if self._obj.on_execute(self.ec_id) != RTC.RTC_OK:
-        self._sm.goTo(RTC.ERROR_STATE)
-        return
-      return
-
-
-    ##
-    # @if jp
-    # @brief RTコンポーネント実行時に定期的に呼ばれる関数
-    #
-    # 管理対象のRTコンポーネントが Active 状態であるとともに、
-    # ExecutionContext が Running 状態の場合に、設定された動作周期で定期的に
-    # 管理対象コンポーネントの on_state_update を呼びだす。
-    # 関数の実行に失敗した場合(返値が RTC_OK 以外)、管理対象コンポーネントの
-    # 状態を Error 状態に遷移させる。
-    #
-    # @param self
-    # @param st 対象RTコンポーネントの現在の状態
-    #
-    # @else
-    #
-    # @endif
-    def on_state_update(self, st):
-      if self._obj.on_state_update(self.ec_id) != RTC.RTC_OK:
-        self._sm.goTo(RTC.ERROR_STATE)
-        return
-      return
-
-
-    ##
-    # @if jp
-    # @brief ExecutionContext の実行周期変更時に呼ばれる関数
-    #
-    # 参加している ExecutionContext の実行周期が変更となった場合に、
-    # 管理対象コンポーネントの on_rate_changed を呼びだす。
-    #
-    # @param self
-    #
-    # @else
-    #
-    # @endif
-    def on_rate_changed(self):
-      self._obj.on_rate_changed(self.ec_id)
-
-
-    ##
-    # @if jp
-    # @brief 状態遷移を実行するワーカーを取得する
-    #
-    # 管理対象RTコンポーネントの状態遷移を実行するワーカーを取得する。
-    #
-    # @param self
-    #
-    # @return ワーカー
-    #
-    # @else
-    #
-    # @brief
-    #
-    # @endif
-    def worker(self):
-      return self._sm.worker()
-
-
-    ##
-    # @if jp
-    # @brief 現在の状態を取得する
-    #
-    # 管理対象RTコンポーネントの現在の状態を取得する。
-    #
-    # @param self
-    #
-    # @return 現在状態
-    #
-    # @else
-    #
-    # @brief
-    #
-    # @endif
-    def get_state(self):
-      return self._sm.getState()
-
-
-  ##
-  # @if jp
   # @brief コンストラクタ
   #
   # コンストラクタ
   # 設定された値をプロファイルに設定する。
   #
-  # @param self
-  # @param owner 当該 Executioncontext の owner(デフォルト値:None)
-  # @param rate 動作周期(Hz)(デフォルト値:None)
-  #
   # @else
   # @brief Constructor
   # @endif
-  def __init__(self, owner=None, rate=None):
+  def __init__(self):
     self._rtcout = OpenRTM_aist.Manager.instance().getLogbuf("rtobject.periodic_ec")
-    self._rtcout.RTC_TRACE("PeriodicExecutionContext()")
-
+    self._rtcout.RTC_TRACE("PeriodicExecutionContext.__init__()")
+    OpenRTM_aist.ExecutionContextBase.__init__(self, "periodic_ec")
     OpenRTM_aist.Task.__init__(self)
 
+    self._svc = False
     self._nowait = False
-    self._running = False
+    self._svcmutex = threading.RLock()
+    self._workerthread = self.WorkerThreadCtrl()
 
-    self._worker = self.Worker()
-
     global DEFAULT_PERIOD
-
-    if rate is None:
-      self._period = OpenRTM_aist.TimeValue(DEFAULT_PERIOD)
-    else:
-      if rate == 0:
-        rate = 1.0 / DEFAULT_PERIOD
-      self._period = OpenRTM_aist.TimeValue(1.0 / rate)
-
-      if self._period.sec() == 0  and self._period.usec() < 0.000001:
-        self._nowait = True
-
+    self.setObjRef(self._this())
+    self.setKind(RTC.PERIODIC)
+    self.setRate(1.0 / DEFAULT_PERIOD)
     self._rtcout.RTC_DEBUG("Actual rate: %d [sec], %d [usec]",
-                           (self._period.sec(), self._period.usec()))    
+                           (self._profile.getPeriod().sec(), self._profile.getPeriod().usec()))    
 
-    self._comps = []
-    self._profile = RTC.ExecutionContextProfile(RTC.PERIODIC, (1.0/self._period.toDouble()), None, [], [])
-    self._ref = self._this()
-    self._mutex_del = threading.RLock()
     return
 
 
   def __del__(self, Task=OpenRTM_aist.Task):
-    self._rtcout.RTC_TRACE("~PeriodicExecutionContext()")
-    self._worker._cond.acquire()
-    self._worker._running = True
-    self._worker._cond.notify()
-    self._worker._cond.release()
-    self._running = False
-    #self.wait()
+    self._rtcout.RTC_TRACE("PeriodicExecutionContext.__del__()")
+    guard = OpenRTM_aist.ScopedLock(self._svcmutex)
+    self._svc = False
+    del guard
 
-    self._profile.owner = None
-    self._profile.paarticipants = []
-    self._profile.properties = []
-    guard = OpenRTM_aist.ScopedLock(self._mutex_del)
-    Task.__del__(self)
+    guard = OpenRTM_aist.ScopedLock(self._workerthread._mutex)
+    self._workerthread._cond.acquire()
+    self._workerthread._running = True
+    self._workerthread._cond.notify()
+    self._workerthread._cond.release()
     del guard
+    self.wait()
+    Task.__del__(self)
+    return
 
-  ##
-  # @if jp
-  # @brief CORBA オブジェクト参照の取得
-  #
-  # 本オブジェクトの ExecutioncontextService としての CORBA オブジェクト参照
-  # を取得する。
-  #
-  # @return CORBA オブジェクト参照
-  #
-  # @param self
-  #
-  # @else
-  #
-  # @endif
-  def getObjRef(self):
-    return self._ref
 
-
   ##
   # @if jp
   # @brief コンポーネントのアクティビティスレッド関数
@@ -434,38 +110,39 @@
   # @endif
   def svc(self):
     self._rtcout.RTC_TRACE("svc()")
-    flag = True
     count_ = 0
     
-    guard = OpenRTM_aist.ScopedLock(self._mutex_del)
-    while flag:
-      self._worker._cond.acquire()
-      while not self._worker._running:
-        self._worker._cond.wait()
+    while self.threadRunning():
+      OpenRTM_aist.ExecutionContextBase.invokeWorkerPreDo(self)
+      # Thread will stopped when all RTCs are INACTIVE.
+      # Therefore WorkerPreDo(updating state) have to be invoked
+      # before stopping thread.
+      guard = OpenRTM_aist.ScopedLock(self._workerthread._mutex)
+      while not self._workerthread._running:
+        self._workerthread._cond.wait()
+      del guard
 
       t0_ = OpenRTM_aist.Time()
-
-      if self._worker._running:
-        for comp in self._comps:
-          comp._sm.worker()
-
-      self._worker._cond.release()
-
+      OpenRTM_aist.ExecutionContextBase.invokeWorkerDo(self)
+      OpenRTM_aist.ExecutionContextBase.invokeWorkerPostDo(self)
       t1_ = OpenRTM_aist.Time()
 
+      period_ = self.getPeriod()
+
       if count_ > 1000:
         exctm_ = (t1_ - t0_).getTime().toDouble()
         slptm_ = self._period.toDouble() - exctm_
-        self._rtcout.RTC_PARANOID("Period:    %f [s]", self._period.toDouble())
+        self._rtcout.RTC_PARANOID("Period:    %f [s]", period_.toDouble())
         self._rtcout.RTC_PARANOID("Execution: %f [s]", exctm_)
         self._rtcout.RTC_PARANOID("Sleep:     %f [s]", slptm_)
 
+
       t2_ = OpenRTM_aist.Time()
 
-      if not self._nowait and self._period.toDouble() > ((t1_ - t0_).getTime().toDouble()):
+      if not self._nowait and period_.toDouble() > ((t1_ - t0_).getTime().toDouble()):
         if count_ > 1000:
           self._rtcout.RTC_PARANOID("sleeping...")
-        slptm_ = self._period.toDouble() - (t1_ - t0_).getTime().toDouble()
+        slptm_ = period_.toDouble() - (t1_ - t0_).getTime().toDouble()
         time.sleep(slptm_)
 
       if count_ > 1000:
@@ -473,13 +150,27 @@
         self._rtcout.RTC_PARANOID("Slept:     %f [s]", (t3_ - t2_).getTime().toDouble())
         count_ = 0
       count_ += 1
-      flag = self._running
-    del guard
+
+    self._rtcout.RTC_DEBUG("Thread terminated.")
     return 0
 
 
   ##
   # @if jp
+  # @brief ExecutionContext用アクティビティスレッドを生成する
+  # @else
+  # @brief Generate internal activity thread for ExecutionContext
+  # @endif
+  #
+  # int PeriodicExecutionContext::open(void *args)
+  def open(self, *args):
+    self._rtcout.RTC_TRACE("open()")
+    self.activate()
+    return 0
+
+
+  ##
+  # @if jp
   # @brief ExecutionContext 用のスレッド実行関数
   #
   # ExecutionContext 用のスレッド終了時に呼ばれる。
@@ -530,7 +221,7 @@
   # @endif
   def is_running(self):
     self._rtcout.RTC_TRACE("is_running()")
-    return self._running
+    return OpenRTM_aist.ExecutionContextBase.isRunning(self)
 
 
   ##
@@ -561,34 +252,9 @@
   #
   # @endif
   def start(self):
-    self._rtcout.RTC_TRACE("start()")
-    if self._running:
-      return RTC.PRECONDITION_NOT_MET
+    return OpenRTM_aist.ExecutionContextBase.start(self)
 
-    for comp in self._comps:
-      comp._sm.on_startup()
 
-    self._running = True
-
-    self._worker._cond.acquire()
-    self._worker._running = True
-    self._worker._cond.notify()
-    self._worker._cond.release()
-
-    try:
-      self.activate()
-    except:
-      self._running = False
-
-      self._worker._cond.acquire()
-      self._worker._running = False
-      self._worker._cond.notify()
-      self._worker._cond.release()
-      self._rtcout.RTC_ERROR(OpenRTM_aist.Logger.print_exception())
-
-    return RTC.RTC_OK
-
-
   ##
   # @if jp
   # @brief ExecutionContext の実行を停止
@@ -616,22 +282,9 @@
   #
   # @endif
   def stop(self):
-    self._rtcout.RTC_TRACE("stop()")
-    if not self._running:
-      return RTC.PRECONDITION_NOT_MET
+    return OpenRTM_aist.ExecutionContextBase.stop(self)
 
-    self._running = False
-    self._worker._cond.acquire()
-    self._worker._running = False
-    self._worker._cond.release()
 
-    for comp in self._comps:
-      comp._sm.on_shutdown()
-
-    #self.wait()
-    return RTC.RTC_OK
-
-
   ##
   # @if jp
   # @brief ExecutionContext の実行周期(Hz)を取得する
@@ -651,8 +304,7 @@
   #
   # @endif
   def get_rate(self):
-    self._rtcout.RTC_TRACE("get_rate()")
-    return self._profile.rate
+    return OpenRTM_aist.ExecutionContextBase.getRate(self)
 
 
   ##
@@ -681,19 +333,9 @@
   #
   # @endif
   def set_rate(self, rate):
-    self._rtcout.RTC_TRACE("set_rate(%f)", rate)
-    if rate > 0.0:
-      self._profile.rate = rate
-      self._period.set_time(1.0/rate)
-      if self._period.toDouble() == 0.0:
-        self._nowait = True
+    return OpenRTM_aist.ExecutionContextBase.setRate(self, rate)
 
-      for comp in self._comps:
-        comp._sm.on_rate_changed()
-      return RTC.RTC_OK
-    return RTC.BAD_PARAMETER
 
-
   ##
   # @if jp
   # @brief RTコンポーネントをアクティブ化する
@@ -724,17 +366,9 @@
   #
   # @endif
   def activate_component(self, comp):
-    self._rtcout.RTC_TRACE("activate_component()")
-    for compIn in self._comps:
-      if compIn._ref._is_equivalent(comp):
-        if not compIn._sm._sm.isIn(RTC.INACTIVE_STATE):
-          return RTC.PRECONDITION_NOT_MET
-        compIn._sm._sm.goTo(RTC.ACTIVE_STATE)
-        return RTC.RTC_OK
+    return OpenRTM_aist.ExecutionContextBase.activateComponent(self, comp)
 
-    return RTC.BAD_PARAMETER
 
-
   ##
   # @if jp
   # @brief RTコンポーネントを非アクティブ化する
@@ -765,32 +399,9 @@
   #
   # @endif
   def deactivate_component(self, comp):
-    self._rtcout.RTC_TRACE("deactivate_component()")
-    for compIn in self._comps:
-      if compIn._ref._is_equivalent(comp):
-        if not compIn._sm._sm.isIn(RTC.ACTIVE_STATE):
-          return RTC.PRECONDITION_NOT_MET
-        compIn._sm._sm.goTo(RTC.INACTIVE_STATE)
-        count_ = 0
-        usec_per_sec_ = 1.0e6
-        sleeptime_ = usec_per_sec_ / float(self.get_rate())
-        self._rtcout.RTC_PARANOID("Sleep time is %f [us]", sleeptime_)
-        while compIn._sm._sm.isIn(RTC.ACTIVE_STATE):
-          self._rtcout.RTC_TRACE("Waiting to be the INACTIVE state %d %f", (count_, float(time.time())))
-          time.sleep(sleeptime_/usec_per_sec_)
-          if count_ > 1000:
-            self._rtcout.RTC_ERROR("The component is not responding.")
-            break
-          count_ += 1
-        if compIn._sm._sm.isIn(RTC.INACTIVE_STATE):
-          self._rtcout.RTC_TRACE("The component has been properly deactivated.")
-          return RTC.RTC_OK
-        self._rtcout.RTC_ERROR("The component could not be deactivated.")
-        return RTC.RTC_ERROR
+    return OpenRTM_aist.ExecutionContextBase.deactivateComponent(self, comp)
 
-    return RTC.BAD_PARAMETER
 
-
   ##
   # @if jp
   # @brief RTコンポーネントをリセットする
@@ -820,17 +431,9 @@
   #
   # @endif
   def reset_component(self, comp):
-    self._rtcout.RTC_TRACE("reset_component()")
-    for compIn in self._comps:
-      if compIn._ref._is_equivalent(comp):
-        if not compIn._sm._sm.isIn(RTC.ERROR_STATE):
-          return RTC.PRECONDITION_NOT_MET
-        compIn._sm._sm.goTo(RTC.INACTIVE_STATE)
-        return RTC.RTC_OK
+    return OpenRTM_aist.ExecutionContextBase.resetComponent(self, comp)
 
-    return RTC.BAD_PARAMETER
 
-
   ##
   # @if jp
   # @brief RTコンポーネントの状態を取得する
@@ -853,14 +456,9 @@
   #
   # @endif
   def get_component_state(self, comp):
-    self._rtcout.RTC_TRACE("get_component_state()")
-    for compIn in self._comps:
-      if compIn._ref._is_equivalent(comp):
-        return compIn._sm._sm.getState()
+    return OpenRTM_aist.ExecutionContextBase.getComponentState(self, comp)
 
-    return RTC.CREATED_STATE
 
-
   ##
   # @if jp
   # @brief ExecutionKind を取得する
@@ -879,8 +477,7 @@
   #
   # @endif
   def get_kind(self):
-    self._rtcout.RTC_TRACE("get_kind()")
-    return self._profile.kind
+    return OpenRTM_aist.ExecutionContextBase.getKind(self)
 
 
   ##
@@ -910,46 +507,9 @@
   #
   # @endif
   def add_component(self, comp):
-    self._rtcout.RTC_TRACE("add_component()")
-    if CORBA.is_nil(comp):
-      return RTC.BAD_PARAMETER
-    try:
-      dfp_  = comp._narrow(OpenRTM.DataFlowComponent)
-      rtc_  = comp._narrow(RTC.RTObject)
-      if CORBA.is_nil(dfp_) or CORBA.is_nil(rtc_):
-        return RTC.BAD_PARAMETER
+    return OpenRTM_aist.ExecutionContextBase.addComponent(self, comp)
 
-      id_   = dfp_.attach_context(self._ref)
-      comp_ = self.Comp(ref=comp, dfp=dfp_, id=id_)
-      self._comps.append(comp_)
-      self._profile.participants.append(rtc_)
-      return RTC.RTC_OK
-    except CORBA.Exception:
-      self._rtcout.RTC_ERROR(OpenRTM_aist.Logger.print_exception())
-      return RTC.BAD_PARAMETER
 
-    return RTC.RTC_OK
-
-
-  def bindComponent(self, rtc):
-    self._rtcout.RTC_TRACE("bindComponent()")
-    if rtc is None:
-      return RTC.BAD_PARAMETER
-
-    comp_ = rtc.getObjRef()
-    dfp_  = comp_._narrow(OpenRTM.DataFlowComponent)
-    id_   = rtc.bindContext(self._ref)
-    if id_ < 0 or id_ > OpenRTM_aist.ECOTHER_OFFSET:
-      self._rtcout.RTC_ERROR("bindContext returns invalid id: %d", id_)
-      return RTC.RTC_ERROR
-
-    self._rtcout.RTC_DEBUG("bindContext returns id = %d", id_)
-    # rtc is owner of this EC
-    self._comps.append(self.Comp(ref=comp_, dfp=dfp_, id=id_))
-    self._profile.owner = dfp_
-    return RTC.RTC_OK
-
-
   ##
   # @if jp
   # @brief RTコンポーネントを参加者リストから削除する
@@ -975,24 +535,9 @@
   #
   # @endif
   def remove_component(self, comp):
-    self._rtcout.RTC_TRACE("remove_component()")
-    len_ = len(self._comps)
-    for i in range(len_):
-      idx = (len_ - 1) - i
-      if self._comps[idx]._ref._is_equivalent(comp):
-        self._comps[idx]._ref.detach_context(self._comps[idx]._sm.ec_id)
-        del self._comps[idx]
-        rtcomp = comp._narrow(RTC.RTObject)
-        if CORBA.is_nil(rtcomp):
-          self._rtcout.RTC_ERROR("Invalid object reference.")
-          return RTC.RTC_ERROR
-        OpenRTM_aist.CORBA_SeqUtil.erase_if(self._profile.participants,
-                                            self.find_participant(rtcomp))
-        return RTC.RTC_OK
+    return OpenRTM_aist.ExecutionContextBase.removeComponent(self, comp)
 
-    return RTC.BAD_PARAMETER
 
-
   ##
   # @if jp
   # @brief ExecutionContextProfile を取得する
@@ -1012,47 +557,161 @@
   #
   # @endif
   def get_profile(self):
-    self._rtcout.RTC_TRACE("get_profile()")
-    return self._profile
+    return OpenRTM_aist.ExecutionContextBase.getProfile(self)
 
 
-  class find_participant:
-    def __init__(self, comp):
-      self._comp = comp
-      return
+  # virtual RTC::ReturnCode_t onStarted();
+  def onStarted(self):
+    # change EC thread state
+    guard = OpenRTM_aist.ScopedLock(self._svcmutex)
+    if not self._svc:
+      self._svc = True
+      self.open(0)
+    del guard
 
-    def __call__(self, comp):
-      return self._comp._is_equivalent(comp)
+    if self.isAllNextState(RTC.INACTIVE_STATE):
+      guard = OpenRTM_aist.ScopedLock(self._workerthread._mutex)
+      self._workerthread._running = False
+      del guard
+    else:
+      guard = OpenRTM_aist.ScopedLock(self._workerthread._mutex)
+      self._workerthread._running = True
+      self._workerthread._cond.signal()
+      del guard
+    return RTC.RTC_OK
 
-      
-  ##
-  # @if jp
-  # @class Comp
-  # @brief コンポーネント管理用内部クラス
-  # @else
-  # @endif
-  class Comp:
-    def __init__(self, ref=None, dfp=None, id=None, comp=None):
-      if comp is None:
-        self._ref = ref
-        self._sm = PeriodicExecutionContext.DFP(dfp,id)
-      else:
-        self._ref = comp._ref
-        self._sm  = PeriodicExecutionContext.DFP(comp._sm._obj,comp._sm.ec_id)
 
+  # virtual RTC::ReturnCode_t onStopping();
+  def onStopping(self):
+    # stop thread
+    guard = OpenRTM_aist.ScopedLock(self._workerthread._mutex)
+    self._workerthread._running = False
+    return RTC.RTC_OK
+
+
+  # virtual RTC::ReturnCode_t
+  # onWaitingActivated(RTC_impl::RTObjectStateMachine* comp, long int count);
+  def onWaitingActivated(self, comp, count):
+    self._rtcout.RTC_TRACE("onWaitingActivated(count = %d)", count)
+    self._rtcout.RTC_PARANOID("curr: %s, next: %s",
+                              self.getStateString(comp.getStates().curr),
+                              self.getStateString(comp.getStates().next))
+    # Now comp's next state must be ACTIVE state
+    # If worker thread is stopped, restart worker thread.
+    guard = OpenRTM_aist.ScopedLock(self._workerthread._mutex)
+    if self._workerthread._running == False:
+      self._workerthread._running = True
+      self._workerthread._cond.signal()
+    del guard
+    return RTC.RTC_OK
+
+
+  # virtual RTC::ReturnCode_t
+  # onActivated(RTC_impl::RTObjectStateMachine* comp, long int count);
+  def onActivated(self, comp, count):
+    self._rtcout.RTC_TRACE("onActivated(count = %d)", count)
+    self._rtcout.RTC_PARANOID("curr: %s, next: %s",
+                              self.getStateString(comp.getStates().curr),
+                              self.getStateString(comp.getStates().next))
+    # count = -1; Asynch mode. Since onWaitingActivated is not
+    # called, onActivated() have to send restart singnal to worker
+    # thread.
+    # count > 0: Synch mode.
+
+    # Now comp's next state must be ACTIVE state
+    # If worker thread is stopped, restart worker thread.
+    guard = OpenRTM_aist.ScopedLock(self._workerthread._mutex)
+    if self._workerthread._running == False:
+      self._workerthread._running = True
+      self._workerthread._cond.signal()
+    del guard
+    return RTC.RTC_OK
+
+
+  # virtual RTC::ReturnCode_t
+  # onWaitingDeactivated(RTC_impl::RTObjectStateMachine* comp, long int count);
+  def onWaitingDeactivated(self, comp, count):
+    self._rtcout.RTC_TRACE("onWaitingDeactivated(count = %d)", count)
+    self._rtcout.RTC_PARANOID("curr: %s, next: %s",
+                              self.getStateString(comp.getStates().curr),
+                              self.getStateString(comp.getStates().next))
+    if self.isAllNextState(RTC.INACTIVE_STATE):
+      guard = OpenRTM_aist.ScopedLock(self._workerthread._mutex)
+      if self._workerthread._running == True:
+        self._workerthread._running = False
+        self._rtcout.RTC_TRACE("All RTCs are INACTIVE. Stopping worker thread.")
+      del guard
+
+    return RTC.RTC_OK
+
+
+  # virtual RTC::ReturnCode_t 
+  # onDeactivated(RTC_impl::RTObjectStateMachine* comp, long int count);
+  def onDeactivated(self, comp, count):
+    self._rtcout.RTC_TRACE("onDeactivated(count = %d)", count)
+    self._rtcout.RTC_PARANOID("curr: %s, next: %s",
+                              self.getStateString(comp.getStates().curr),
+                              self.getStateString(comp.getStates().next))
+    if self.isAllNextState(RTC.INACTIVE_STATE):
+      guard = OpenRTM_aist.ScopedLock(self._workerthread._mutex)
+      if self._workerthread._running == True:
+        self._workerthread._running = False
+        self._rtcout.RTC_TRACE("All RTCs are INACTIVE. Stopping worker thread.")
+      del guard
+
+    return RTC.RTC_OK
+
+
+  # virtual RTC::ReturnCode_t
+  # onWaitingReset(RTC_impl::RTObjectStateMachine* comp, long int count);
+  def onWaitingReset(self, comp, count):
+    self._rtcout.RTC_TRACE("onWaitingReset(count = %d)", count)
+    self._rtcout.RTC_PARANOID("curr: %s, next: %s",
+                              self.getStateString(comp.getStates().curr),
+                              self.getStateString(comp.getStates().next))
+    if self.isAllNextState(RTC.INACTIVE_STATE):
+      guard = OpenRTM_aist.ScopedLock(self._workerthread._mutex)
+      if self._workerthread._running == True:
+        self._workerthread._running = False
+        self._rtcout.RTC_TRACE("All RTCs are INACTIVE. Stopping worker thread.")
+      del guard
+
+    return RTC.RTC_OK
+
+
+  # virtual RTC::ReturnCode_t 
+  # onReset(RTC_impl::RTObjectStateMachine* comp, long int count);
+  def onReset(self, comp, count):
+    self._rtcout.RTC_TRACE("onReset(count = %d)", count)
+    self._rtcout.RTC_PARANOID("curr: %s, next: %s",
+                              self.getStateString(comp.getStates().curr),
+                              self.getStateString(comp.getStates().next))
+    if self.isAllNextState(RTC.INACTIVE_STATE):
+      guard = OpenRTM_aist.ScopedLock(self._workerthread._mutex)
+      if self._workerthread._running == True:
+        self._workerthread._running = False
+        self._rtcout.RTC_TRACE("All RTCs are INACTIVE. Stopping worker thread.")
+      del guard
+
+    return RTC.RTC_OK
+    return
+
+  # bool threadRunning()
+  def threadRunning(self):
+    guard = OpenRTM_aist.ScopedLock(self._svcmutex)
+    return self._svc
+
+
   ##
   # @if jp
-  # @class Worker
-  # @brief ExecutionContext 駆動クラス
+  # @class WorkerThreadCtrl
+  # @brief worker 用状態変数クラス
   #
-  # 実行処理に関する排他制御など、実際の処理を監視・制御するためのクラス。
-  #
-  # @since 0.4.0
-  #
   # @else
-  #
+  # @class WorkerThreadCtrl
+  # @brief Condition variable class for worker
   # @endif
-  class Worker:
+  class WorkerThreadCtrl:
     
     ##
     # @if jp

Modified: branches/work/OpenRTM-aist-Python/OpenRTM_aist/test/test_PeriodicExecutionContext.py
===================================================================
--- branches/work/OpenRTM-aist-Python/OpenRTM_aist/test/test_PeriodicExecutionContext.py	2012-03-13 07:15:16 UTC (rev 526)
+++ branches/work/OpenRTM-aist-Python/OpenRTM_aist/test/test_PeriodicExecutionContext.py	2012-03-13 07:43:23 UTC (rev 527)
@@ -165,7 +165,7 @@
     self._dfp = DFP()
     self._dfp._poa._get_the_POAManager().activate()
 
-    self._pec = PeriodicExecutionContext(self._dfp._ref, 10)
+    self._pec = PeriodicExecutionContext()
     self._pec.add_component(self._dfp.getRef())
     self._pec.start()
   



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