00001 //================================================================================================== 00002 // Copyright (C) 2010 Brian Tietz sdbtietz at yahoo dot com 00003 // 00004 // This program is free software; you can redistribute it and/or modify it under the terms of the 00005 // GNU General Public License as published by the Free Software Foundation, version 2.0 of the 00006 // License. 00007 // 00008 // This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without 00009 // even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00010 // General Public License for more details. 00011 // 00012 // You should have received a copy of the GNU General Public License along with this program; if 00013 // not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 00014 // 02110-1301, USA. 00015 // 00016 // For commercial software, the copyright holder (Brian Tietz, email sdbtietz at yahoo dot com) 00017 // reserves the right and is willing to waive the proprietary source code disclosure aspects of that 00018 // license as applied to the UT library in exchange for either substantial contributions to the 00019 // development of the UT library or other forms of compensation. Any such waiver must be 00020 // established in writing between the copyright holder and the commercial entity obtaining such a 00021 // waiver. 00022 //================================================================================================== 00023 00024 00025 #ifndef _UT_IDLE_TASK_H_ 00026 #define _UT_IDLE_TASK_H_ 00027 00028 00029 //================================================================================================== 00030 //=== Project headers 00031 //================================================================================================== 00032 #include "UTMessageLoop.h" 00033 #include "UTMutex.h" 00034 #include "UTIdleAddRemoveTask.h" 00035 00036 00037 //================================================================================================== 00038 class UT_EXPORT IdleTask_t 00039 //================================================================================================== 00040 : public Task_t, 00041 private BTreeNode_t< IdleTask_t, roughtime_t > 00048 { 00049 //---------------------------------------------------------------------------------------------- 00050 public: 00051 //---------------------------------------------------------------------------------------------- 00052 inline IdleTask_t(int32 poll_interval_seconds); 00055 00056 inline void SetPollInterval(int32 poll_interval_seconds); 00060 00061 virtual void PerformIdleWork() = 0; 00063 00064 //---------------------------------------------------------------------------------------------- 00065 private: 00066 //---------------------------------------------------------------------------------------------- 00067 inline int Compare(roughtime_t poll_time) const; 00068 inline operator roughtime_t() const; 00069 00070 //---------------------------------------------------------------------------------------------- 00071 private: 00072 //---------------------------------------------------------------------------------------------- 00073 int32 m_poll_interval_ms; 00074 roughtime_t m_next_poll_time; 00075 00076 friend class BTreeNode_t< IdleTask_t, roughtime_t >; 00077 friend class BTree_t< IdleTask_t, roughtime_t >; 00078 friend class IdleMessageLoop_t; 00079 }; 00080 00081 00082 // \cond DOXYGEN_DOCUMENT_NEVER 00083 00084 #if SYSTEM_TIME_MAX_INTERVAL_SECONDS 00085 00086 //================================================================================================== 00087 class SystemTimeProtectTask_t 00088 //================================================================================================== 00089 : public IdleTask_t 00090 { 00091 //---------------------------------------------------------------------------------------------- 00092 public: 00093 //---------------------------------------------------------------------------------------------- 00094 SystemTimeProtectTask_t(); 00095 virtual void PerformIdleWork(); 00096 }; 00097 00098 #endif // SYSTEM_TIME_MAX_INTERVAL_SECONDS 00099 00100 // \endcond 00101 00102 00103 //================================================================================================== 00104 class UT_EXPORT IdleMessageLoop_t 00105 //================================================================================================== 00106 : public MessageLoop_t 00111 { 00112 //---------------------------------------------------------------------------------------------- 00113 public: 00114 //---------------------------------------------------------------------------------------------- 00115 IdleMessageLoop_t(); 00118 00119 ~IdleMessageLoop_t(); 00123 00124 void AddIdleTask(IdleTask_t* task); 00128 00129 void RemoveIdleTask(IdleTask_t* task); 00132 00133 //---------------------------------------------------------------------------------------------- 00134 protected: 00135 //---------------------------------------------------------------------------------------------- 00136 // \cond DOXYGEN_DOCUMENT_NEVER 00137 virtual void Timeout(); 00138 // \endcond 00139 00140 //---------------------------------------------------------------------------------------------- 00141 private: 00142 //---------------------------------------------------------------------------------------------- 00143 void StartIdleThread(); 00144 void SetPollInterval( IdleTask_t* task, int32 poll_interval_seconds ); 00145 #if SYSTEM_TIME_MAX_INTERVAL_SECONDS 00146 void StartSystemTimeProtection(); 00147 #endif 00148 00149 void ResetTimeout(roughtime_t now); 00150 00151 void Shutdown(); 00152 00153 //---------------------------------------------------------------------------------------------- 00154 private: 00155 //---------------------------------------------------------------------------------------------- 00156 volatile bool m_running; 00157 volatile bool m_system_time_protected; 00158 00159 BTree_t< IdleTask_t, roughtime_t > m_idle_tasks; 00160 IdleAddRemoveTask_t m_add_remove_task; 00161 MessageDestination_t<IdleAddRemoveMessage_t> m_add_destination; 00162 MessageDestination_t<IdleAddRemoveMessage_t> m_remove_destination; 00163 00164 #if SYSTEM_TIME_MAX_INTERVAL_SECONDS 00165 SystemTimeProtectTask_t m_system_time_protect_task; 00166 #endif 00167 00168 Mutex_t m_start_or_remove_mutex; 00169 Event_t m_remove_complete_event; 00170 00171 static IdleMessageLoop_t* ms_singleton; 00172 00173 friend class IdleTask_t; 00174 friend class SystemTimeManager_t; 00175 friend class Thread_t; 00176 friend class IdleAddRemoveTask_t; 00177 }; 00178 00179 00180 extern UT_EXPORT IdleMessageLoop_t g_idle_message_loop; 00181 00182 00183 00184 00185 //================================================================================================== 00186 //================================================================================================== 00187 //=== 00188 //=== Inline function implementations 00189 //=== 00190 //================================================================================================== 00191 //================================================================================================== 00192 inline 00193 IdleTask_t::IdleTask_t(int32 poll_interval_seconds) 00194 { 00195 assert(poll_interval_seconds >= 2 && poll_interval_seconds <= 1073741); 00196 m_poll_interval_ms = poll_interval_seconds * 1000; 00197 } 00198 00199 00200 inline void 00201 IdleTask_t::SetPollInterval(int32 poll_interval_seconds) 00202 { 00203 assert(poll_interval_seconds >= 2 && poll_interval_seconds <= 1073741); 00204 if( !MessageLoop() ) 00205 { 00206 m_poll_interval_ms = poll_interval_seconds * 1000; 00207 return; 00208 } 00209 IdleMessageLoop_t::ms_singleton->SetPollInterval( this, poll_interval_seconds ); 00210 } 00211 00212 00213 inline int 00214 IdleTask_t::Compare(roughtime_t poll_time) const 00215 { 00216 if(m_next_poll_time > poll_time) 00217 return 1; 00218 else if(m_next_poll_time < poll_time) 00219 return -1; 00220 return 0; 00221 } 00222 00223 00224 inline 00225 IdleTask_t::operator roughtime_t() const 00226 { 00227 return m_next_poll_time; 00228 } 00229 00230 00231 #endif // _UT_IDLE_TASK_H_