[openrtm-commit:00686] r2326 - in trunk/OpenRTM-aist/src/ext: . ec ec/rtpreempt

openrtm @ openrtm.org openrtm @ openrtm.org
2012年 2月 9日 (木) 10:17:19 JST


Author: n-ando
Date: 2012-02-09 10:17:19 +0900 (Thu, 09 Feb 2012)
New Revision: 2326

Modified:
   trunk/OpenRTM-aist/src/ext/Makefile.am
   trunk/OpenRTM-aist/src/ext/ec/Makefile.am
   trunk/OpenRTM-aist/src/ext/ec/rtpreempt/RTPreemptEC.cpp
   trunk/OpenRTM-aist/src/ext/ec/rtpreempt/RTPreemptEC.h
Log:
[compat,impl/makefile,bigfix] RTPreemptEC has been updated for new ECBase. refs #2366


Modified: trunk/OpenRTM-aist/src/ext/Makefile.am
===================================================================
--- trunk/OpenRTM-aist/src/ext/Makefile.am	2012-02-09 01:13:25 UTC (rev 2325)
+++ trunk/OpenRTM-aist/src/ext/Makefile.am	2012-02-09 01:17:19 UTC (rev 2326)
@@ -7,6 +7,6 @@
 
 AUTOMAKE_OPTIONS = 1.4
 
-SUBDIRS = ec sdo
+SUBDIRS = local_service ec sdo 
 
 

Modified: trunk/OpenRTM-aist/src/ext/ec/Makefile.am
===================================================================
--- trunk/OpenRTM-aist/src/ext/ec/Makefile.am	2012-02-09 01:13:25 UTC (rev 2325)
+++ trunk/OpenRTM-aist/src/ext/ec/Makefile.am	2012-02-09 01:17:19 UTC (rev 2326)
@@ -7,7 +7,7 @@
 
 AUTOMAKE_OPTIONS = 1.4
 
-#SUBDIRS = @ARTLINUX@ @RTPREEMPTEC@
+SUBDIRS = @ARTLINUX@ @RTPREEMPTEC@
 
-#DIST_SUBDIRS = artlinux rtpreempt logical_time
-SUBDIRS = logical_time
\ No newline at end of file
+DIST_SUBDIRS = artlinux rtpreempt logical_time
+#SUBDIRS = logical_time

Modified: trunk/OpenRTM-aist/src/ext/ec/rtpreempt/RTPreemptEC.cpp
===================================================================
--- trunk/OpenRTM-aist/src/ext/ec/rtpreempt/RTPreemptEC.cpp	2012-02-09 01:13:25 UTC (rev 2325)
+++ trunk/OpenRTM-aist/src/ext/ec/rtpreempt/RTPreemptEC.cpp	2012-02-09 01:17:19 UTC (rev 2326)
@@ -2,75 +2,65 @@
 /*!
  * @file RTPreemptEC.cpp
  * @brief RTPreemptEC class
- * @date $Date$
+ * @date $Date: 2008-01-14 07:53:01 $
  * @author Noriaki Ando <n-ando at aist.go.jp>
  *
- * Copyright (C) 2010
+ * Copyright (C) 2006-2008,2012
+ *     Noriaki Ando
  *     Intelligent Systems Research Institute,
  *     National Institute of
  *         Advanced Industrial Science and Technology (AIST), Japan
  *     All rights reserved.
  *
- * $Id$
+ * $Id: RTPreemptEC.cpp 2307 2012-02-05 21:29:15Z n-ando $
  *
  */
 
-#include "RTPreemptEC.h"
 #include <stdlib.h>
 #include <stdio.h>
 #include <time.h>
 #include <sched.h>
 #include <sys/mman.h>
-#include <string.h>
-#include <rtm/ECFactory.h>
-#include <rtm/Manager.h>
-#include <coil/stringutil.h>
 
+#include <algorithm>
+#include <iostream>
+
+#include <coil/Time.h>
+#include <coil/TimeValue.h>
+
+#include <rtm/RTObjectStateMachine.h>
+#include <RTPreemptEC.h>
+
 #define MAX_SAFE_STACK (8*1024)
 #define NSEC_PER_SEC 1000000000
+#define DEEFAULT_PERIOD 0.000001
 
-namespace OpenRTM
+namespace RTC_exp
 {
   /*!
    * @if jp
    * @brief デフォルトコンストラクタ
    * @else
-   * @brief Default Constructor
+   * @brief Default constructor
    * @endif
    */
-  RTPreemptEC::RTPreemptEC()
-    : ::RTC::PeriodicExecutionContext(),
-      m_priority(49), m_policy(SCHED_FIFO), m_waitoffset(0)
+  RTPreemptEC::
+  RTPreemptEC()
+    : ExecutionContextBase("periodic_ec"),
+      rtclog("periodic_ec"),
+      m_svc(false), m_nowait(false)
   {
-    rtclog.setName("RTPreemptEC");
-    coil::Properties& prop(::RTC::Manager::instance().getConfig());
+    RTC_TRACE(("RTPreemptEC()"));
 
-    // Priority
-    getProperty(prop, "exec_cxt.periodic.priority", m_priority);
-    getProperty(prop, "exec_cxt.periodic.rtpreempt.priority", m_priority);
-    RTC_DEBUG(("Priority: %d", m_priority));
+    // getting my reference
+    setObjRef(this->_this());
 
-    // Policy
-    {
-      std::string policy;
-      getProperty(prop, "exec_cxt.periodic.rtpreempt.sched_policy", policy);
-      if (!policy.empty())
-        {
-          coil::normalize(policy);
-          if (policy == "rr")   { m_policy = SCHED_RR; }
-          if (policy == "fifo") { m_policy = SCHED_FIFO; }
-          RTC_DEBUG(("Scheduling policy: %s", policy.c_str()));
-        }
-      else
-        {
-          RTC_DEBUG(("Scheduling policy: fifo"));
-        }
-    }
+    // profile initialization
+    setKind(RTC::PERIODIC);
+    setRate(1.0 / (double)DEEFAULT_PERIOD);
 
-    // Wait offset
-    getProperty(prop, "exec_cxt.periodic.rtpreempt.wait_offset", m_waitoffset);
-    RTC_DEBUG(("Wait offset: %d [ns]", m_waitoffset));
-    
+    RTC_DEBUG(("Actual period: %d [sec], %d [usec]",
+               m_profile.getPeriod().sec(), m_profile.getPeriod().usec()));
   }
 
   /*!
@@ -82,88 +72,586 @@
    */
   RTPreemptEC::~RTPreemptEC()
   {
+    RTC_TRACE(("~RTPreemptEC()"));
+    {
+      Guard guard(m_svcmutex);
+      m_svc = false;
+    }
+    {
+      Guard guard(m_workerthread.mutex_);
+      m_workerthread.running_ = true;
+      m_workerthread.cond_.signal();
+    }
+    wait();
   }
 
+  void RTPreemptEC::init(coil::Properties& props)
+  {
+    RTC_TRACE(("init()"));
+    ExecutionContextBase::init(props);
+
+    setPriority(props);
+    setPolicy(props);
+    setWaitOffset(props);
+
+    RTC_DEBUG(("init() done"));
+  }
+
+
+  /*------------------------------------------------------------
+   * Start activity
+   * ACE_Task class method over ride.
+   *------------------------------------------------------------*/
   /*!
    * @if jp
+   * @brief ExecutionContext用アクティビティスレッドを生成する
+   * @else
+   * @brief Generate internal activity thread for ExecutionContext
+   * @endif
+   */
+  int RTPreemptEC::open(void *args)
+  {
+    RTC_TRACE(("open()"));
+    activate();
+    return 0;
+  }
+
+  /*------------------------------------------------------------
+   * Run by a daemon thread to handle deferred processing
+   * ACE_Task class method over ride.
+   *------------------------------------------------------------*/
+  /*!
+   * @if jp
    * @brief ExecutionContext 用のスレッド実行関数
    * @else
    * @brief Thread execution function for ExecutionContext
    * @endif
-   */ 
-  int RTPreemptEC::svc(void)
+   */
+  bool RTPreemptEC::prepareThread()
   {
-    // schedulaer setting
     struct sched_param param;
     param.sched_priority = m_priority;
     if(sched_setscheduler(0, m_policy, &param) == -1)
       {
         std::cerr << "sched_setscheduler failed" << std::endl;
-        return -1;
+        return false;
       }
 
     // memory locking
     if(mlockall(MCL_CURRENT | MCL_FUTURE) == -1)
       {
         std::cerr << "mlockall failed" << std::endl;
-        return -1;
+        return false;
       }
+    return true;
+  }
+  int RTPreemptEC::svc(void)
+  {
+    RTC_TRACE(("svc()"));
+    if (!prepareThread()) { return -1; }
 
     // stack preallocation
     unsigned char dummy[MAX_SAFE_STACK];
     memset(&dummy, 0, MAX_SAFE_STACK);
-    struct timespec t0, t1, t;
+
+    struct timespec ts0, ts1, ts2, ts3;
+    int count(0);
     do
       {
-        clock_gettime(CLOCK_MONOTONIC ,&t0);
-        m_worker.mutex_.lock();
-        while (!m_worker.running_)
+        ExecutionContextBase::invokeWorkerPreDo();
+        {
+          Guard guard(m_workerthread.mutex_);
+          while (!m_workerthread.running_)
+            {
+              m_workerthread.cond_.wait();
+            }
+        }
+        clock_gettime(CLOCK_MONOTONIC ,&ts0);
+        coil::TimeValue t0(ts0.tv_sec, ts0.tv_nsec * 1000);
+        ExecutionContextBase::invokeWorkerDo();
+        ExecutionContextBase::invokeWorkerPostDo();
+        clock_gettime(CLOCK_MONOTONIC ,&ts1);
+        coil::TimeValue t1(ts1.tv_sec, ts1.tv_nsec * 1000);
+
+        coil::TimeValue period(getPeriod());
+        if (count > 1000)
           {
-            m_worker.cond_.wait();
+            RTC_PARANOID(("Period:    %f [s]", (double)period));
+            RTC_PARANOID(("Execution: %f [s]", (double)(t1 - t0)));
+            RTC_PARANOID(("Sleep:     %f [s]", (double)(period - (t1 - t0))));
           }
-        if (m_worker.running_)
-          {
-            std::for_each(m_comps.begin(), m_comps.end(), invoke_worker());
-          }
-        m_worker.mutex_.unlock();
-        clock_gettime(CLOCK_MONOTONIC ,&t1);
+        clock_gettime(CLOCK_MONOTONIC ,&ts2);
+        coil::TimeValue t2(ts2.tv_sec, ts2.tv_nsec * 1000);
+        if (m_nowait) { ++count; continue; }
 
-        if (!m_nowait)
+        struct timespec sleeptime;
+        if (getSleepTime(sleeptime, ts0, ts1) == true)
           {
-            if (t0.tv_nsec > t1.tv_nsec)
+            clock_nanosleep(CLOCK_MONOTONIC, !TIMER_ABSTIME,
+                            &sleeptime, NULL);
+            if (count > 1000)
               {
-                t.tv_nsec = m_period.usec() * 1000
-                  - (NSEC_PER_SEC - t0.tv_nsec + t1.tv_nsec) + m_waitoffset;
-                t.tv_sec  = m_period.sec()
-                  - (t1.tv_sec - 1 - t0.tv_sec);
+                clock_gettime(CLOCK_MONOTONIC ,&ts3);
+                coil::TimeValue t3(ts3.tv_sec, ts3.tv_nsec * 1000);
+                RTC_PARANOID(("Slept:     %f [s]", (double)(t3 - t2)));
+                count = 0;
               }
-            else
-              {
-                t.tv_nsec = m_period.usec() * 1000
-                  - (t1.tv_nsec - t0.tv_nsec) + m_waitoffset;
-                t.tv_sec  = m_period.sec()
-                  - (t1.tv_sec - t0.tv_sec);
-              }
-
-            if (t.tv_nsec < 0 || t.tv_sec < 0)
-              {
-                std::cerr << "faital error: deadline passed. " << std::endl;
-                std::cerr << "Wait time: ";
-                std::cerr << t.tv_sec << "[s], ";
-                std::cerr << t.tv_nsec << "[ns]" << std::endl;
-                std::cerr << "Next wait time force to: 0.0 [s]" << std::endl;
-                continue;
-              }
-            clock_nanosleep(CLOCK_MONOTONIC, !TIMER_ABSTIME, &t, NULL);
           }
-      } while (m_svc);
- 
+        ++count;
+      } while (threadRunning());
+    RTC_DEBUG(("Thread terminated."));
     return 0;
   }
 
-};
+  /*!
+   * @if jp
+   * @brief ExecutionContext 用のスレッド実行関数
+   * @else
+   * @brief Thread execution function for ExecutionContext
+   * @endif
+   */
+  int RTPreemptEC::close(unsigned long flags)
+  {
+    RTC_TRACE(("close()"));
+    // At this point, this component have to be finished.
+    // Current state and Next state should be RTC_EXITING.
+    return 0;
+  }
 
 
+  //============================================================
+  // ExecutionContext CORBA operations
+  //============================================================
+  /*!
+   * @if jp
+   * @brief ExecutionContext 実行状態確認関数
+   * @else
+   * @brief Check for ExecutionContext running state
+   * @endif
+   */
+  CORBA::Boolean RTPreemptEC::is_running()
+    throw (CORBA::SystemException)
+  {
+    return ExecutionContextBase::isRunning();
+  }
+
+  /*!
+   * @if jp
+   * @brief ExecutionContext の実行を開始
+   * @else
+   * @brief Start the ExecutionContext
+   * @endif
+   */
+  RTC::ReturnCode_t RTPreemptEC::start()
+    throw (CORBA::SystemException)
+  {
+    return ExecutionContextBase::start();
+  }
+
+  /*!
+   * @if jp
+   * @brief ExecutionContext の実行を停止
+   * @else
+   * @brief Stop the ExecutionContext
+   * @endif
+   */
+  RTC::ReturnCode_t RTPreemptEC::stop()
+    throw (CORBA::SystemException)
+  {
+    return ExecutionContextBase::stop();
+  }
+
+
+
+  /*!
+   * @if jp
+   * @brief ExecutionContext の実行周期(Hz)を取得する
+   * @else
+   * @brief Get execution rate(Hz) of ExecutionContext
+   * @endif
+   */
+  CORBA::Double RTPreemptEC::get_rate()
+    throw (CORBA::SystemException)
+  {
+    return ExecutionContextBase::getRate();
+  }
+
+  /*!
+   * @if jp
+   * @brief ExecutionContext の実行周期(Hz)を設定する
+   * @else
+   * @brief Set execution rate(Hz) of ExecutionContext
+   * @endif
+   */
+  RTC::ReturnCode_t RTPreemptEC::set_rate(CORBA::Double rate)
+    throw (CORBA::SystemException)
+  {
+    return ExecutionContextBase::setRate(rate);
+  }
+
+  /*!
+   * @if jp
+   * @brief RTコンポーネントを追加する
+   * @else
+   * @brief Add an RT-Component
+   * @endif
+   */
+  RTC::ReturnCode_t
+  RTPreemptEC::add_component(RTC::LightweightRTObject_ptr comp)
+    throw (CORBA::SystemException)
+  {
+    return ExecutionContextBase::addComponent(comp);
+  }
+
+  /*!
+   * @if jp
+   * @brief コンポーネントをコンポーネントリストから削除する
+   * @else
+   * @brief Remove the RT-Component from participant list
+   * @endif
+   */
+  RTC::ReturnCode_t RTPreemptEC::
+  remove_component(RTC::LightweightRTObject_ptr comp)
+    throw (CORBA::SystemException)
+  {
+    return ExecutionContextBase::removeComponent(comp);
+  }
+
+  /*!
+   * @if jp
+   * @brief RTコンポーネントをアクティブ化する
+   * @else
+   * @brief Activate an RT-Component
+   * @endif
+   */
+  RTC::ReturnCode_t RTPreemptEC::
+  activate_component(RTC::LightweightRTObject_ptr comp)
+    throw (CORBA::SystemException)
+  {
+    return ExecutionContextBase::activateComponent(comp);
+  }
+
+  /*!
+   * @if jp
+   * @brief RTコンポーネントを非アクティブ化する
+   * @else
+   * @brief Deactivate an RT-Component
+   * @endif
+   */
+  RTC::ReturnCode_t RTPreemptEC::
+  deactivate_component(RTC::LightweightRTObject_ptr comp)
+    throw (CORBA::SystemException)
+  {
+    return ExecutionContextBase::deactivateComponent(comp);
+  }
+
+  /*!
+   * @if jp
+   * @brief RTコンポーネントをリセットする
+   * @else
+   * @brief Reset the RT-Component
+   * @endif
+   */
+  RTC::ReturnCode_t RTPreemptEC::
+  reset_component(RTC::LightweightRTObject_ptr comp)
+    throw (CORBA::SystemException)
+  {
+    return ExecutionContextBase::resetComponent(comp);
+  }
+
+  /*!
+   * @if jp
+   * @brief RTコンポーネントの状態を取得する
+   * @else
+   * @brief Get RT-Component's state
+   * @endif
+   */
+  RTC::LifeCycleState RTPreemptEC::
+  get_component_state(RTC::LightweightRTObject_ptr comp)
+    throw (CORBA::SystemException)
+  {
+    RTC::LifeCycleState ret = ExecutionContextBase::getComponentState(comp);
+    return ret;
+  }
+
+  /*!
+   * @if jp
+   * @brief ExecutionKind を取得する
+   * @else
+   * @brief Get the ExecutionKind
+   * @endif
+   */
+  RTC::ExecutionKind RTPreemptEC::get_kind()
+    throw (CORBA::SystemException)
+  {
+    return ExecutionContextBase::getKind();
+  }
+
+  //------------------------------------------------------------
+  // ExecutionContextService interfaces
+  //------------------------------------------------------------
+  /*!
+   * @if jp
+   * @brief ExecutionContextProfile を取得する
+   * @else
+   * @brief Get the ExecutionContextProfile
+   * @endif
+   */
+  RTC::ExecutionContextProfile* RTPreemptEC::get_profile()
+    throw (CORBA::SystemException)
+  {
+    return ExecutionContextBase::getProfile();
+  }
+
+
+  //============================================================
+  // protected functions
+  //============================================================
+  /*!
+   * @brief onStarted() template function
+   */
+  RTC::ReturnCode_t RTPreemptEC::onStarted()
+  {
+    // change EC thread state
+    {
+      Guard guard(m_svcmutex);
+      if (!m_svc)
+        {
+          m_svc = true;
+          this->open(0);
+        }
+    }
+    if (isAllNextState(RTC::INACTIVE_STATE))
+      {
+        Guard guard(m_workerthread.mutex_);
+        m_workerthread.running_ = false;
+      }
+    else
+      {
+        Guard guard(m_workerthread.mutex_);
+        m_workerthread.running_ = true;
+        m_workerthread.cond_.signal();
+      }
+    return RTC::RTC_OK;
+  }
+
+  /*!
+   * @brief onStopping() template function
+   */
+  RTC::ReturnCode_t RTPreemptEC::onStopping()
+  {
+    // stop thread
+    Guard guard(m_workerthread.mutex_);
+    m_workerthread.running_ = false;
+    return RTC::RTC_OK;
+  }
+
+  /*!
+   * @brief onWaitingActivated() template function
+   */
+  RTC::ReturnCode_t RTPreemptEC::
+  onWaitingActivated(RTC_impl::RTObjectStateMachine* comp, long int count)
+  {
+    RTC_TRACE(("onWaitingActivated(count = %d)", count));
+    RTC_PARANOID(("curr: %s, next: %s",
+                  getStateString(comp->getStates().curr),
+                  getStateString(comp->getStates().next)));
+    // Now comp's next state must be ACTIVE state
+    // If worker thread is stopped, restart worker thread.
+    Guard guard(m_workerthread.mutex_);
+    if (m_workerthread.running_ == false)
+      {
+        m_workerthread.running_ = true;
+        m_workerthread.cond_.signal();
+      }
+    return RTC::RTC_OK;
+  }
+
+  /*!
+   * @brief onActivated() template function
+   */
+  RTC::ReturnCode_t RTPreemptEC::
+  onActivated(RTC_impl::RTObjectStateMachine* comp, long int count)
+  {
+    RTC_TRACE(("onActivated(count = %d)", count));
+    RTC_PARANOID(("curr: %s, next: %s",
+                  getStateString(comp->getStates().curr),
+                  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 guard(m_workerthread.mutex_);
+    if (m_workerthread.running_ == false)
+      {
+        m_workerthread.running_ = true;
+        m_workerthread.cond_.signal();
+      }
+    return RTC::RTC_OK;
+  }
+
+  /*!
+   * @brief onWaitingDeactivated() template function
+   */
+  RTC::ReturnCode_t RTPreemptEC::
+  onWaitingDeactivated(RTC_impl::RTObjectStateMachine* comp, long int count)
+  {
+    RTC_TRACE(("onWaitingDeactivated(count = %d)", count));
+    RTC_PARANOID(("curr: %s, next: %s",
+                  getStateString(comp->getStates().curr),
+                  getStateString(comp->getStates().next)));
+    if (isAllNextState(RTC::INACTIVE_STATE))
+      {
+        Guard guard(m_workerthread.mutex_);
+        if (m_workerthread.running_ == true)
+          {
+            m_workerthread.running_ = false;
+            RTC_TRACE(("All RTCs are INACTIVE. Stopping worker thread."));
+          }
+      }
+    return RTC::RTC_OK;
+  }
+
+  /*!
+   * @brief onDeactivated() template function
+   */
+  RTC::ReturnCode_t RTPreemptEC::
+  onDeactivated(RTC_impl::RTObjectStateMachine* comp, long int count)
+  {
+    RTC_TRACE(("onDeactivated(count = %d)", count));
+    RTC_PARANOID(("curr: %s, next: %s",
+                  getStateString(comp->getStates().curr),
+                  getStateString(comp->getStates().next)));
+    if (isAllNextState(RTC::INACTIVE_STATE))
+      {
+        Guard guard(m_workerthread.mutex_);
+        if (m_workerthread.running_ == true)
+          {
+            m_workerthread.running_ = false;
+            RTC_TRACE(("All RTCs are INACTIVE. Stopping worker thread."));
+          }
+      }
+    return RTC::RTC_OK;
+  }
+
+  /*!
+   * @brief onWaitingReset() template function
+   */
+  RTC::ReturnCode_t RTPreemptEC::
+  onWaitingReset(RTC_impl::RTObjectStateMachine* comp, long int count)
+  {
+    RTC_TRACE(("onWaitingReset(count = %d)", count));
+    RTC_PARANOID(("curr: %s, next: %s",
+                  getStateString(comp->getStates().curr),
+                  getStateString(comp->getStates().next)));
+    if (isAllNextState(RTC::INACTIVE_STATE))
+      {
+        Guard guard(m_workerthread.mutex_);
+        if (m_workerthread.running_ == true)
+          {
+            m_workerthread.running_ = false;
+            RTC_TRACE(("All RTCs are INACTIVE. Stopping worker thread."));
+          }
+      }
+    return RTC::RTC_OK;
+  }
+
+  /*!
+   * @brief onReset() template function
+   */
+  RTC::ReturnCode_t RTPreemptEC::
+  onReset(RTC_impl::RTObjectStateMachine* comp, long int count)
+  {
+    RTC_TRACE(("onReset(count = %d)", count));
+    RTC_PARANOID(("curr: %s, next: %s",
+                  getStateString(comp->getStates().curr),
+                  getStateString(comp->getStates().next)));
+    if (isAllNextState(RTC::INACTIVE_STATE))
+      {
+        Guard guard(m_workerthread.mutex_);
+        if (m_workerthread.running_ == true)
+          {
+            m_workerthread.running_ = false;
+            RTC_TRACE(("All RTCs are INACTIVE. Stopping worker thread."));
+          }
+      }
+    return RTC::RTC_OK;
+  }
+
+  //============================================================
+  // private functions
+  //============================================================
+  void RTPreemptEC::
+  setPriority(coil::Properties& prop)
+  {
+    RTC_TRACE(("setPriority()"));
+    getProperty(prop, "priority", m_priority);
+
+
+    RTC_DEBUG(("setPriority(): priority: %d", m_priority));
+  }
+  void RTPreemptEC::
+  setPolicy(coil::Properties& prop)
+  {
+    RTC_TRACE(("setPriority()"));
+    std::string policy;
+    getProperty(prop, "priority", policy);
+    if (!policy.empty())
+      {
+        coil::normalize(policy);
+        if (policy == "rr")   { m_policy = SCHED_RR; }
+        if (policy == "fifo") { m_policy = SCHED_FIFO; }
+        RTC_DEBUG(("Scheduling policy: %s", policy.c_str()));
+      }
+    else
+      {
+        RTC_DEBUG(("Scheduling policy: fifo"));
+        m_policy = SCHED_FIFO;
+      }
+    RTC_DEBUG(("setPolicy(): policy: %s", policy.c_str()));
+  }
+  void RTPreemptEC::
+  setWaitOffset(coil::Properties& prop)
+  {
+    RTC_TRACE(("setWaitOffset()"));
+    getProperty(prop, "wait_offset", m_waitoffset);
+    RTC_DEBUG(("setWaitOffset(): offset: %d", m_waitoffset));
+  }
+
+  bool RTPreemptEC::getSleepTime(struct timespec& ts,
+                                 const struct timespec& t0,
+                                 const struct timespec& t1)
+  {
+    coil::TimeValue period(getPeriod());
+    if (t0.tv_nsec > t1.tv_nsec)
+      {
+        ts.tv_nsec = period.usec() * 1000
+          - (NSEC_PER_SEC - t0.tv_nsec + t1.tv_nsec) + m_waitoffset;
+        ts.tv_sec  = period.sec() - (t1.tv_sec - 1 - t0.tv_sec);
+      }
+    else
+      {
+        ts.tv_nsec = period.usec() * 1000
+          - (t1.tv_nsec - t0.tv_nsec) + m_waitoffset;
+        ts.tv_sec  = period.sec() - (t1.tv_sec - t0.tv_sec);
+      }
+    if (ts.tv_nsec < 0 || ts.tv_sec < 0)
+      {
+        std::cerr << "faital error: deadline passed. " << std::endl;
+        std::cerr << "Wait time: ";
+        std::cerr << ts.tv_sec << "[s], ";
+        std::cerr << ts.tv_nsec << "[ns]" << std::endl;
+        std::cerr << "Next wait time force to: 0.0 [s]"
+                  << std::endl;
+        return false; // sleeptime < 0
+      }
+    return true; // sleeptime >= 0
+  }
+}; // namespace RTC
+
 extern "C"
 {
   /*!
@@ -173,12 +661,18 @@
    * @brief Initialization function to register to ECFactory
    * @endif
    */
-  void RTPreemptECInit(RTC::Manager* manager)
+
+ void RTPreemptECInit(RTC::Manager* manager)
   {
-    RTC::Manager::instance().
-      registerECFactory("RTPreemptEC",
-                        RTC::ECCreate<OpenRTM::RTPreemptEC>,
-                        RTC::ECDelete<OpenRTM::RTPreemptEC>);
-    
+    RTC::ExecutionContextFactory::
+      instance().addFactory("RTPreemptEC",
+                            ::coil::Creator< ::RTC::ExecutionContextBase,
+                            ::RTC_exp::RTPreemptEC>,
+                            ::coil::Destructor< ::RTC::ExecutionContextBase,
+                            ::RTC_exp::RTPreemptEC>);
+
+    coil::vstring ecs;
+    ecs = RTC::ExecutionContextFactory::instance().getIdentifiers();
   }
 };
+

Modified: trunk/OpenRTM-aist/src/ext/ec/rtpreempt/RTPreemptEC.h
===================================================================
--- trunk/OpenRTM-aist/src/ext/ec/rtpreempt/RTPreemptEC.h	2012-02-09 01:13:25 UTC (rev 2325)
+++ trunk/OpenRTM-aist/src/ext/ec/rtpreempt/RTPreemptEC.h	2012-02-09 01:17:19 UTC (rev 2326)
@@ -2,27 +2,39 @@
 /*!
  * @file RTPreemptEC.h
  * @brief RTPreemptEC class
- * @date $Date$
+ * @date $Date: 2008-01-14 07:53:05 $
  * @author Noriaki Ando <n-ando at aist.go.jp>
  *
- * Copyright (C) 2010
+ * Copyright (C) 2006-2008,2012
+ *     Noriaki Ando
  *     Intelligent Systems Research Institute,
  *     National Institute of
  *         Advanced Industrial Science and Technology (AIST), Japan
  *     All rights reserved.
  *
- * $Id$
+ * $Id: RTPreemptEC.h 2307 2012-02-05 21:29:15Z n-ando $
  *
  */
 
-#ifndef OPENRTM_RTPREEMPTEC_H
-#define OPENRTM_RTPREEMPTEC_H
+#ifndef RTC_RTPREEMPTEC2_H
+#define RTC_RTPREEMPTEC2_H
 
-#include <rtm/RTC.h>
-#include <rtm/Manager.h>
-#include <rtm/PeriodicExecutionContext.h>
+#include <vector>
+#include <iostream>
 
-namespace OpenRTM
+#include <coil/Task.h>
+#include <coil/Mutex.h>
+#include <coil/Condition.h>
+
+#include <rtm/ExecutionContextBase.h>
+
+#define NUM_OF_LIFECYCLESTATE 4
+
+#ifdef WIN32
+#pragma warning( disable : 4290 )
+#endif
+
+namespace RTC_exp
 {
   /*!
    * @if jp
@@ -35,11 +47,11 @@
    * リング機能を利用した実行コンテキストである。
    *
    * この実行コンテキストを利用するには、rtc.conf に下記のように記述する。
-   * 
+   *
    * <pre>
-   * exec_cxt.periodic.type: RTPreemptEC
-   * exec_cxt.periodic.rate: 1000
-   * exec_cxt.priority: 50
+   * execution_contexts: rtpreempt_ec
+   * ec.rtpreempt_ec.rate: 1000
+   * ec.rtpreempt_ec.priority: 50
    * manager.modules.load_path: <RTPreemptRC.so がある場所へのパス>
    * manager.modules.preload: RTPreemptEC.so
    * </pre>
@@ -49,17 +61,16 @@
    *
    * このECに特有なオプションは以下のとおりである。
    *
-   * - exec_cxt.periodic.priority: (default: 49) <br>
-   * - exec_cxt.periodic.rtpreempt.priority: (default: 49)<br>
+   * - ec.rtpreempt_ec.priority: (default: 49) <br>
    *      スレッドの実行優先度 1 (最低) から 99 (最高)<br>
    *      Linux sched_setscheduler(2) を参照のこと。<br>
    *
-   * - exec_cxt.periodic.rtpreempt.sched_policy:  (default: fifo)<br>
+   * - ec.rtpreempt_ec.sched_policy:  (default: fifo)<br>
    *      スケジューリングのポリシ。<br>
    *      rr: ラウンドロビン, fifo: FIFO 型 (default: fifo)<br>
    *      Linux sched_setscheduler(2) を参照のこと。<br>
    *
-   * - exec_cxt.periodic.rtpreempt.wait_offset: (default: -10000)<br>
+   * - ec.rtpeempt_ec.wait_offset: (default: -10000)<br>
    *      ウェイト時間のオフセット。[ns] 単位で指定する。 <br>
    *      1周期あたり数十 us 程度の定常的な遅れが発生する場合があるので、
    *      この値を調整することで、より正確な周期で実行させることができる。
@@ -98,8 +109,8 @@
    *
    * - exec_cxt.periodic.priority: (default: 49)<br>
    * - exec_cxt.periodic.rtpreempt.priority: (default: 49)<br>
-   *      Execution priority of threads from 1 (lowest) to 99 (highest)<br>
-   *      See Linux sched_setscheduler(2).
+   *     Execution priority of threads from 1 (lowest) to 99 (highest)<br>
+   *     See Linux sched_setscheduler(2).
    *
    * - exec_cxt.periodic.rtpreempt.sched_policy:  (default: fifo)<br>
    *      Scheduling policy.<br>
@@ -124,19 +135,29 @@
    * @endif
    */
   class RTPreemptEC
-    : public virtual ::RTC::PeriodicExecutionContext
+    : public virtual POA_RTC::ExecutionContextService,
+      public virtual PortableServer::RefCountServantBase,
+      public RTC::ExecutionContextBase,
+      public coil::Task
   {
+    typedef coil::Guard<coil::Mutex> Guard;
   public:
     /*!
      * @if jp
      * @brief デフォルトコンストラクタ
      *
      * デフォルトコンストラクタ
+     * プロファイルに以下の項目を設定する。
+     *  - kind : PERIODIC
+     *  - rate : 0.0
      *
      * @else
      * @brief Default Constructor
      *
      * Default Constructor
+     * Set the following items to profile.
+     *  - kind : PERIODIC
+     *  - rate : 0.0
      *
      * @endif
      */
@@ -155,31 +176,542 @@
      *
      * @endif
      */
-    virtual ~RTPreemptEC();
+    virtual ~RTPreemptEC(void);
 
     /*!
      * @if jp
+     * @brief ExecutionContextの処理を進める
+     *
+     * ExecutionContextの処理を1周期分進める。
+     *
+     * @else
+     * @brief Proceed with tick of ExecutionContext
+     *
+     * Proceed with tick of ExecutionContext for one period.
+     *
+     * @endif
+     */
+    void init(coil::Properties& props);
+
+    /*!
+     * @if jp
+     * @brief ExecutionContext用アクティビティスレッドを生成する
+     *
+     * Executioncontext 用の内部アクティビティスレッドを生成し起動する。
+     * これは coil::Task サービスクラスメソッドのオーバーライド。
+     *
+     * @param args 通常は0
+     *
+     * @return 生成処理実行結果
+     *
+     * @else
+     *
+     * @brief Generate internal activity thread for ExecutionContext
+     *
+     * Generate internal activity thread and run.  This is coil::Task
+     * class method's override.
+     *
+     * @param args Usually give 0
+     *
+     * @return The generation result
+     *
+     * @endif
+     */
+    virtual int open(void *args);
+
+    /*!
+     * @if jp
      * @brief ExecutionContext 用のスレッド実行関数
      *
-     * ExecutionContext 用のスレッド実行関数。
-     * 登録されたコンポーネントの処理を呼び出す。
+     * ExecutionContext 用のスレッド実行関数。登録されたコンポーネント
+     * の処理を呼び出す。
      *
      * @return 実行結果
      *
      * @else
      * @brief Thread execution function for ExecutionContext
      *
-     * Thread execution function for ExecutionContext.
-     * Invoke the registered components operation.
+     * Thread execution function for ExecutionContext.  Invoke the
+     * registered components operation.
      *
      * @return The execution result
      *
      * @endif
-     */ 
+     */
     virtual int svc(void);
 
     /*!
      * @if jp
+     * @brief ExecutionContext 用のスレッド実行関数
+     *
+     * ExecutionContext 用のスレッド終了時に呼ばれる。コンポーネントオ
+     * ブジェクトの非アクティブ化、マネージャへの通知を行う。これは
+     * coil::Task サービスクラスメソッドのオーバーライド。
+     *
+     * @param flags 終了処理フラグ
+     *
+     * @return 終了処理結果
+     *
+     * @else
+     *
+     * @brief Thread execution function for ExecutionContext
+     *
+     * This function is invoked when activity thread for
+     * ExecutionContext exits.  Deactivate the component object and
+     * notify it to manager.  This is coil::Task class method's
+     * override.
+     *
+     * @param flags Flag of the close
+     *
+     * @return The close result
+     *
+     * @endif
+     */
+    virtual int close(unsigned long flags);
+
+    //============================================================
+    // ExecutionContext
+    //============================================================
+    /*!
+     * @if jp
+     * @brief ExecutionContext 実行状態確認関数
+     *
+     * この操作は ExecutionContext が Runnning 状態の場合に true を返す。
+     * Executioncontext が Running の間、当該 Executioncontext に参加し
+     * ている全てのアクティブRTコンポーネントが、ExecutionContext の実
+     * 行種類に応じて実行される。
+     *
+     * @return 状態確認関数(動作中:true、停止中:false)
+     *
+     * @else
+     *
+     * @brief Check for ExecutionContext running state
+     *
+     * This operation shall return true if the context is in the
+     * Running state.  While the context is Running, all Active RTCs
+     * participating in the context shall be executed according to the
+     * context’s execution kind.
+     *
+     * @return Check state function (Running:true、Stopping:false)
+     *
+     * @endif
+     */
+    virtual CORBA::Boolean is_running(void)
+      throw (CORBA::SystemException);
+
+    /*!
+     * @if jp
+     * @brief ExecutionContext の実行を開始
+     *
+     * ExecutionContext の実行状態を Runnning とするためのリクエストを
+     * 発行する。ExecutionContext の状態が遷移すると
+     * ComponentAction::on_startup が呼び出される。参加しているRTコンポー
+     * ネントが、初期化されるまで ExecutionContext を開始することはでき
+     * ない。ExecutionContext は複数回開始/停止を繰り返すことができる。
+     *
+     * @return ReturnCode_t 型のリターンコード
+     *
+     * @else
+     *
+     * @brief Start the ExecutionContext
+     *
+     * Request that the context enter the Running state.  Once the
+     * state transition occurs, the ComponentAction::on_startup
+     * operation will be invoked.  An execution context may not be
+     * started until the RT-Components that participate in it have
+     * been initialized.  An execution context may be started and
+     * stopped multiple times.
+     *
+     * @return The return code of ReturnCode_t type
+     *
+     * @endif
+     */
+    virtual RTC::ReturnCode_t start(void)
+      throw (CORBA::SystemException);
+
+    /*!
+     * @if jp
+     * @brief ExecutionContext の実行を停止
+     *
+     * ExecutionContext の状態を Stopped とするためのリクエストを発行す
+     * る。遷移が発生した場合は、ComponentAction::on_shutdown が呼び出
+     * される。参加しているRTコンポーネントが終了する前に
+     * ExecutionContext を停止する必要がある。ExecutionContext は複数回
+     * 開始/停止を繰り返すことができる。
+     *
+     * @return ReturnCode_t 型のリターンコード
+     *
+     * @else
+     *
+     * @brief Stop the ExecutionContext
+     *
+     * Request that the context enter the Stopped state.  Once the
+     * transition occurs, the ComponentAction::on_shutdown operation
+     * will be invoked.  An execution context must be stopped before
+     * the RT components that participate in it are finalized.  An
+     * execution context may be started and stopped multiple times.
+     *
+     * @return The return code of ReturnCode_t type
+     *
+     * @endif
+     */
+    virtual RTC::ReturnCode_t stop(void)
+      throw (CORBA::SystemException);
+
+    /*!
+     * @if jp
+     * @brief ExecutionContext の実行周期(Hz)を取得する
+     *
+     * Active 状態にてRTコンポーネントが実行される周期(単位:Hz)を取得す
+     * る。
+     *
+     * @return 処理周期(単位:Hz)
+     *
+     * @else
+     *
+     * @brief Get execution rate(Hz) of ExecutionContext
+     *
+     * This operation shall return the rate (in hertz) at which its
+     * Active participating RTCs are being invoked.
+     *
+     * @return Execution cycle(Unit:Hz)
+     *
+     * @endif
+     */
+    virtual CORBA::Double get_rate(void)
+      throw (CORBA::SystemException);
+
+    /*!
+     * @if jp
+     * @brief ExecutionContext の実行周期(Hz)を設定する
+     *
+     * Active 状態にてRTコンポーネントが実行される周期(単位:Hz)を設定す
+     * る。実行周期の変更は、DataFlowComponentAction の
+     * on_rate_changed によって各RTコンポーネントに伝達される。
+     *
+     * @param rate 処理周期(単位:Hz)
+     *
+     * @return ReturnCode_t 型のリターンコード
+     *
+     * @else
+     *
+     * @brief Set execution rate(Hz) of ExecutionContext
+     *
+     * This operation shall set the rate (in hertz) at which this
+     * context’s Active participating RTCs are being called.  If the
+     * execution kind of the context is PERIODIC, a rate change shall
+     * result in the invocation of on_rate_changed on any RTCs
+     * realizing DataFlowComponentAction that are registered with any
+     * RTCs participating in the context.
+     *
+     * @param rate Execution cycle(Unit:Hz)
+     *
+     * @return The return code of ReturnCode_t type
+     *
+     * @endif
+     */
+    virtual RTC::ReturnCode_t  set_rate(CORBA::Double rate)
+      throw (CORBA::SystemException);
+
+    /*!
+     * @if jp
+     * @brief RTコンポーネントをアクティブ化する
+     *
+     * Inactive 状態にあるRTコンポーネントをActive に遷移させ、アクティ
+     * ブ化する。この操作が呼ばれた結果、on_activate が呼び出される。指
+     * 定したRTコンポーネントが参加者リストに含まれない場合は、
+     * BAD_PARAMETER が返される。指定したRTコンポーネントの状態が
+     * Inactive 以外の場合は、PRECONDITION_NOT_MET が返される。
+     *
+     * @param comp アクティブ化対象RTコンポーネント
+     *
+     * @return ReturnCode_t 型のリターンコード
+     *
+     * @else
+     *
+     * @brief Activate an RT-component
+     *
+     * The given participant RTC is Inactive and is therefore not
+     * being invoked according to the execution context’s execution
+     * kind. This operation shall cause the RTC to transition to the
+     * Active state such that it may subsequently be invoked in this
+     * execution context.  The callback on_activate shall be called as
+     * a result of calling this operation. This operation shall not
+     * return until the callback has returned, and shall result in an
+     * error if the callback does.
+     *
+     * @param comp The target RT-Component for activation
+     *
+     * @return The return code of ReturnCode_t type
+     *
+     * @endif
+     */
+    virtual RTC::ReturnCode_t
+    activate_component(RTC::LightweightRTObject_ptr comp)
+      throw (CORBA::SystemException);
+
+    /*!
+     * @if jp
+     * @brief RTコンポーネントを非アクティブ化する
+     *
+     * Inactive 状態にあるRTコンポーネントを非アクティブ化し、Inactive
+     * に遷移させる。この操作が呼ばれた結果、on_deactivate が呼び出され
+     * る。指定したRTコンポーネントが参加者リストに含まれない場合は、
+     * BAD_PARAMETER が返される。指定したRTコンポーネントの状態が
+     * Active 以外の場合は、PRECONDITION_NOT_MET が返される。
+     *
+     * @param comp 非アクティブ化対象RTコンポーネント
+     *
+     * @return ReturnCode_t 型のリターンコード
+     *
+     * @else
+     *
+     * @brief Deactivate an RT-component
+     *
+     * The given RTC is Active in the execution context. Cause it to
+     * transition to the Inactive state such that it will not be
+     * subsequently invoked from the context unless and until it is
+     * activated again.  The callback on_deactivate shall be called as
+     * a result of calling this operation. This operation shall not
+     * return until the callback has returned, and shall result in an
+     * error if the callback does.
+     *
+     * @param comp The target RT-Component for deactivate
+     *
+     * @return The return code of ReturnCode_t type
+     *
+     * @endif
+     */
+    virtual RTC::ReturnCode_t
+    deactivate_component(RTC::LightweightRTObject_ptr comp)
+      throw (CORBA::SystemException);
+
+    /*!
+     * @if jp
+     * @brief RTコンポーネントをリセットする
+     *
+     * Error 状態のRTコンポーネントの復帰を試みる。この操作が呼ばれた結
+     * 果、on_reset が呼び出される。指定したRTコンポーネントが参加者リ
+     * ストに含まれない場合は、BAD_PARAMETER が返される。指定したRTコン
+     * ポーネントの状態が Error 以外の場合は、PRECONDITION_NOT_MET が返
+     * される。
+     *
+     * @param comp リセット対象RTコンポーネント
+     *
+     * @return ReturnCode_t 型のリターンコード
+     *
+     * @else
+     *
+     * @brief Reset the RT-component
+     *
+     * Attempt to recover the RTC when it is in Error.  The
+     * ComponentAction::on_reset callback shall be invoked. This
+     * operation shall not return until the callback has returned, and
+     * shall result in an error if the callback does. If possible, the
+     * RTC developer should implement that callback such that the RTC
+     * may be returned to a valid state.
+     *
+     * @param comp The target RT-Component for reset
+     *
+     * @return The return code of ReturnCode_t type
+     *
+     * @endif
+     */
+    virtual RTC::ReturnCode_t
+    reset_component(RTC::LightweightRTObject_ptr comp)
+      throw (CORBA::SystemException);
+
+    /*!
+     * @if jp
+     * @brief RTコンポーネントの状態を取得する
+     *
+     * 指定したRTコンポーネントの状態(LifeCycleState)を取得する。指定し
+     * たRTコンポーネントが参加者リストに含まれない場合は、
+     * UNKNOWN_STATE が返される。
+     *
+     * @param comp 状態取得対象RTコンポーネント
+     *
+     * @return 現在の状態(LifeCycleState)
+     *
+     * @else
+     *
+     * @brief Get RT-component's state
+     *
+     * This operation shall report the LifeCycleState of the given
+     * participant RTC.  UNKNOWN_STATE will be returned, if the given
+     * RT-Component is not inclued in the participant list.
+     *
+     * @param comp The target RT-Component to get the state
+     *
+     * @return The current state of the target RT-Component(LifeCycleState)
+     *
+     * @endif
+     */
+    virtual RTC::LifeCycleState
+    get_component_state(RTC::LightweightRTObject_ptr comp)
+      throw (CORBA::SystemException);
+
+    /*!
+     * @if jp
+     * @brief ExecutionKind を取得する
+     *
+     * 本 ExecutionContext の ExecutionKind を取得する
+     *
+     * @return ExecutionKind
+     *
+     * @else
+     *
+     * @brief Get the ExecutionKind
+     *
+     * This operation shall report the execution kind of the execution
+     * context.
+     *
+     * @return ExecutionKind
+     *
+     * @endif
+     */
+    virtual RTC::ExecutionKind get_kind(void)
+      throw (CORBA::SystemException);
+
+    /*!
+     * @if jp
+     * @brief RTコンポーネントを追加する
+     *
+     * 指定したRTコンポーネントを参加者リストに追加する。追加されたRTコ
+     * ンポーネントは attach_context が呼ばれ、Inactive 状態に遷移する。
+     * 指定されたRTコンポーネントがnullの場合は、BAD_PARAMETER が返され
+     * る。指定されたRTコンポーネントが DataFlowComponent 以外の場合は、
+     * BAD_PARAMETER が返される。
+     *
+     * @param comp 追加対象RTコンポーネント
+     *
+     * @return ReturnCode_t 型のリターンコード
+     *
+     * @else
+     *
+     * @brief Add an RT-component
+     *
+     * The operation causes the given RTC to begin participating in
+     * the execution context.  The newly added RTC will receive a call
+     * to LightweightRTComponent::attach_context and then enter the
+     * Inactive state.  BAD_PARAMETER will be invoked, if the given
+     * RT-Component is null or if the given RT-Component is other than
+     * DataFlowComponent.
+     *
+     * @param comp The target RT-Component for add
+     *
+     * @return The return code of ReturnCode_t type
+     *
+     * @endif
+     */
+    virtual RTC::ReturnCode_t
+    add_component(RTC::LightweightRTObject_ptr comp)
+      throw (CORBA::SystemException);
+
+    /*!
+     * @if jp
+     * @brief RTコンポーネントを参加者リストから削除する
+     *
+     * 指定したRTコンポーネントを参加者リストから削除する。削除された
+     * RTコンポーネントは detach_context が呼ばれる。指定されたRTコンポー
+     * ネントが参加者リストに登録されていない場合は、BAD_PARAMETER が返
+     * される。
+     *
+     * @param comp 削除対象RTコンポーネント
+     *
+     * @return ReturnCode_t 型のリターンコード
+     *
+     * @else
+     *
+     * @brief Remove the RT-Component from participant list
+     *
+     * This operation causes a participant RTC to stop participating
+     * in the execution context.  The removed RTC will receive a call
+     * to LightweightRTComponent::detach_context.  BAD_PARAMETER will
+     * be returned, if the given RT-Component is not participating in
+     * the participant list.
+     *
+     * @param comp The target RT-Component for delete
+     *
+     * @return The return code of ReturnCode_t type
+     *
+     * @endif
+     */
+    virtual RTC::ReturnCode_t
+    remove_component(RTC::LightweightRTObject_ptr comp)
+      throw (CORBA::SystemException);
+
+    /*!
+     * @if jp
+     * @brief ExecutionContextProfile を取得する
+     *
+     * 本 ExecutionContext のプロファイルを取得する。
+     *
+     * @return ExecutionContextProfile
+     *
+     * @else
+     *
+     * @brief Get the ExecutionContextProfile
+     *
+     * This operation provides a profile “descriptor” for the execution
+     * context.
+     *
+     * @return ExecutionContextProfile
+     *
+     * @endif
+     */
+    virtual RTC::ExecutionContextProfile* get_profile(void)
+      throw (CORBA::SystemException);
+
+  protected:
+    /*!
+     * @brief onStarted() template function
+     */
+    virtual RTC::ReturnCode_t onStarted();
+    /*!
+     * @brief onStopping() template function
+     */
+    virtual RTC::ReturnCode_t onStopping();
+    /*!
+     * @brief onWaitingActivated() template function
+     */
+    virtual RTC::ReturnCode_t
+    onWaitingActivated(RTC_impl::RTObjectStateMachine* comp, long int count);
+    /*!
+     * @brief onActivated() template function
+     */
+    virtual RTC::ReturnCode_t
+    onActivated(RTC_impl::RTObjectStateMachine* comp, long int count);
+    /*!
+     * @brief onWaitingDeactivated() template function
+     */
+    virtual RTC::ReturnCode_t
+    onWaitingDeactivated(RTC_impl::RTObjectStateMachine* comp,
+                         long int count);
+    /*!
+     * @brief onDeactivated() template function
+     */
+    virtual RTC::ReturnCode_t 
+    onDeactivated(RTC_impl::RTObjectStateMachine* comp, long int count);
+    /*!
+     * @brief onWaitingReset() template function
+     */
+    virtual RTC::ReturnCode_t
+    onWaitingReset(RTC_impl::RTObjectStateMachine* comp, long int count);
+    /*!
+     * @brief onReset() template function
+     */
+    virtual RTC::ReturnCode_t 
+    onReset(RTC_impl::RTObjectStateMachine* comp, long int count);
+
+    bool threadRunning()
+    {
+      Guard guard(m_svcmutex);
+      return m_svc;
+    }
+
+    /*!
+     * @if jp
      * @brief あるキーを持つプロパティを取得する
      *
      * @param ExecutionContext 用のスレッド実行関数。
@@ -196,7 +728,7 @@
      * @return The execution result
      *
      * @endif
-     */ 
+     */
     template <class T>
     void getProperty(coil::Properties& prop, const char* key, T& value)
     {
@@ -211,12 +743,80 @@
     }
 
   private:
+    bool prepareThread();
+    void setPriority(coil::Properties& prop);
+    void setPolicy(coil::Properties& prop);
+    void setWaitOffset(coil::Properties& prop);
+    bool getSleepTime(struct timespec& ts,
+                      const struct timespec& t0,
+                      const struct timespec& t1);
+
+  protected:
+    /*!
+     * @if jp
+     * @brief ロガーストリーム
+     * @else
+     * @brief Logger stream
+     * @endif
+     */
+    RTC::Logger rtclog;
+
+    /*!
+     * @if jp
+     * @brief ExecutionContext のスレッド実行フラグ
+     * @else
+     * @brief The thread running flag of ExecutionContext
+     * @endif
+     */
+    bool m_svc;
+    coil::Mutex m_svcmutex;
+    
+    /*!
+     * @if jp
+     * @brief worker 用状態変数クラス
+     * @else
+     * @brief Condition variable class for worker
+     * @endif
+     */
+    struct WorkerThreadCtrl
+    {
+      WorkerThreadCtrl() : cond_(mutex_), running_(false) {};
+      coil::Mutex mutex_;
+      coil::Condition<coil::Mutex> cond_;
+      bool running_;
+    };
+
+    /*!
+     * @if jp
+     * @brief svn用の状態変数 
+     * @else
+     * @brief A condition variable for external triggered worker
+     * @endif
+     */
+    WorkerThreadCtrl m_workerthread;
+
+    /*!
+     * @if jp
+     * @brief ExecutionContext 即時実行(wait無し実行)フラグ
+     * @else
+     * @brief Flag of ExecutionContext to run immediately
+     *        (to run without waiting)
+     * @endif
+     */
+    bool m_nowait;
+
+  private:
     int m_priority;
     int m_policy;
     int m_waitoffset;
-  };
-};
+  }; // class RTPreemptEC
+}; // namespace RTC
 
+#ifdef WIN32
+#pragma warning( default : 4290 )
+#endif
+
+
 extern "C"
 {
   /*!
@@ -226,8 +826,7 @@
    * @brief Initialization function to register to ECFactory
    * @endif
    */
-  void DLL_EXPORT RTPreemptECInit(RTC::Manager* manager);
+  void RTPreemptECInit(RTC::Manager* manager);
 };
 
-#endif // OPENRTM_RTPREEMPTEC_H
-
+#endif // RTC_RTPREEMPTEC_H



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