诸暨麻将添加redis
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

374 lines
9.6 KiB

  1. #include "StdAfx.h"
  2. #include "TimerEngine.h"
  3. #include "TraceService.h" //
  4. //宏定义
  5. #define NO_TIME_LEFT DWORD(-1) //不响应时间
  6. //////////////////////////////////////////////////////////////////////////
  7. //构造函数
  8. CTimerThread::CTimerThread(void)
  9. {
  10. m_pTimerEngine = NULL;
  11. }
  12. //析构函数
  13. CTimerThread::~CTimerThread(void)
  14. {
  15. }
  16. //配置函数
  17. bool CTimerThread::InitThread(CTimerEngine * pTimerEngine)
  18. {
  19. if (pTimerEngine == NULL) return false;
  20. //设置变量
  21. m_pTimerEngine = pTimerEngine;
  22. return true;
  23. }
  24. //运行函数
  25. bool CTimerThread::OnEventThreadRun()
  26. {
  27. ASSERT(m_pTimerEngine != NULL);
  28. DWORD dwNow = ::timeGetTime();
  29. m_pTimerEngine->OnTimerThreadSink(dwNow);
  30. Sleep(1);
  31. // Sleep(TIMER_SPACE); //magiii 12/04/01/ Sleep误差太大,太不靠谱了,改成上面的方式
  32. // m_pTimerEngine->OnTimerThreadSink();
  33. return true;
  34. }
  35. //////////////////////////////////////////////////////////////////////////
  36. //构造函数
  37. CTimerEngine::CTimerEngine(void)
  38. {
  39. m_bService = false;
  40. m_pIQueueServiceSink = NULL;
  41. }
  42. //析构函数
  43. CTimerEngine::~CTimerEngine(void)
  44. {
  45. INT_PTR i = 0;
  46. //停止服务
  47. ConcludeService();
  48. //清理内存
  49. tagTimerItem * pTimerItem = NULL;
  50. for (i = 0; i < m_TimerItemFree.GetCount(); i++)
  51. {
  52. pTimerItem = m_TimerItemFree[i];
  53. ASSERT(pTimerItem != NULL);
  54. SafeDelete(pTimerItem);
  55. }
  56. for (i = 0; i < m_TimerItemActive.GetCount(); i++)
  57. {
  58. pTimerItem = m_TimerItemActive[i];
  59. ASSERT(pTimerItem != NULL);
  60. SafeDelete(pTimerItem);
  61. }
  62. m_TimerItemFree.RemoveAll();
  63. m_TimerItemActive.RemoveAll();
  64. return;
  65. }
  66. //接口查询
  67. void * CTimerEngine::QueryInterface(const IID & Guid, DWORD dwQueryVer)
  68. {
  69. QUERYINTERFACE(ITimerEngine, Guid, dwQueryVer);
  70. QUERYINTERFACE_IUNKNOWNEX(ITimerEngine, Guid, dwQueryVer);
  71. return NULL;
  72. }
  73. //设置定时器
  74. bool CTimerEngine::SetTimer(DWORD dwTimerID, DWORD dwElapse, DWORD dwRepeat, WPARAM dwBindParameter)
  75. {
  76. //锁定资源
  77. CWHDataLocker lock(m_CriticalSection);//
  78. //效验参数
  79. ASSERT(dwRepeat > 0L);
  80. if (dwRepeat == 0) return false;
  81. //查找定时器
  82. bool bTimerExist = false;
  83. tagTimerItem * pTimerItem = NULL;
  84. for (INT_PTR i = 0; i < m_TimerItemActive.GetCount(); i++)
  85. {
  86. pTimerItem = m_TimerItemActive[i];
  87. ASSERT(pTimerItem != NULL);
  88. if (pTimerItem->wTimerID == dwTimerID)
  89. {
  90. bTimerExist = true;
  91. break;
  92. }
  93. }
  94. //创建定时器
  95. if (bTimerExist == false)
  96. {
  97. INT_PTR nFreeCount = m_TimerItemFree.GetCount();
  98. if (nFreeCount > 0)
  99. {
  100. pTimerItem = m_TimerItemFree[nFreeCount - 1];
  101. ASSERT(pTimerItem != NULL);
  102. m_TimerItemFree.RemoveAt(nFreeCount - 1);
  103. }
  104. else
  105. {
  106. try
  107. {
  108. pTimerItem = new tagTimerItem;
  109. ASSERT(pTimerItem != NULL);
  110. if (pTimerItem == NULL) return false;
  111. }
  112. catch (...)
  113. {
  114. return false;
  115. }
  116. }
  117. }
  118. //设置参数
  119. ASSERT(pTimerItem != NULL);
  120. pTimerItem->wTimerID = dwTimerID;
  121. pTimerItem->wBindParam = dwBindParameter;
  122. pTimerItem->dwElapse = dwElapse;
  123. pTimerItem->dwRepeatTimes = dwRepeat;
  124. //提前20个粒度进行通知 - TIMER_SPACE * 20
  125. //if (pTimerItem->dwRepeatTimes == 1)
  126. // pTimerItem->dwTimeLeave = __max(TIMER_SPACE, pTimerItem->dwElapse - TIMER_SPACE * 20);
  127. //else
  128. // pTimerItem->dwTimeLeave = pTimerItem->dwElapse;
  129. pTimerItem->dwTimeStart = ::timeGetTime();
  130. //激活定时器
  131. if (bTimerExist == false)
  132. m_TimerItemActive.Add(pTimerItem);
  133. return true;
  134. }
  135. //删除定时器
  136. bool CTimerEngine::KillTimer(DWORD dwTimerID)
  137. {
  138. //锁定资源
  139. CWHDataLocker lock(m_CriticalSection);//
  140. //查找定时器
  141. tagTimerItem * pTimerItem = NULL;
  142. for (INT_PTR i = 0; i < m_TimerItemActive.GetCount(); i++)
  143. {
  144. pTimerItem = m_TimerItemActive[i];
  145. ASSERT(pTimerItem != NULL);
  146. if (pTimerItem->wTimerID == dwTimerID)
  147. {
  148. m_TimerItemActive.RemoveAt(i);
  149. m_TimerItemFree.Add(pTimerItem);
  150. return true;;
  151. }
  152. }
  153. return false;
  154. }
  155. //删除定时器
  156. bool CTimerEngine::KillAllTimer()
  157. {
  158. //锁定资源
  159. CWHDataLocker lock(m_CriticalSection);//
  160. //删除定时器
  161. m_TimerItemFree.Append(m_TimerItemActive);
  162. m_TimerItemActive.RemoveAll();
  163. return true;
  164. }
  165. //开始服务
  166. bool CTimerEngine::StartService()
  167. {
  168. //效验状态
  169. if (m_bService == true)
  170. {
  171. CTraceService::TraceString(TEXT("定时器引擎重复启动,启动操作忽略"), TraceLevel_Warning);
  172. return true;
  173. }
  174. //设置变量
  175. if (m_TimerThread.InitThread(this) == false)
  176. {
  177. CTraceService::TraceString(TEXT("定时器引擎线程服务初始化失败"), TraceLevel_Exception);
  178. return false;
  179. }
  180. //启动服务
  181. if (m_TimerThread.StartThread() == false)
  182. {
  183. CTraceService::TraceString(TEXT("定时器引擎线程服务启动失败"), TraceLevel_Exception);
  184. return false;
  185. }
  186. SetThreadPriority(m_TimerThread.GetThreadHandle(), REALTIME_PRIORITY_CLASS);
  187. //设置变量
  188. m_bService = true;
  189. return true;
  190. }
  191. //停止服务
  192. bool CTimerEngine::ConcludeService()
  193. {
  194. //设置变量
  195. m_bService = false;
  196. //停止线程
  197. m_TimerThread.ConcludeThread(INFINITE);
  198. //设置变量
  199. m_TimerItemFree.Append(m_TimerItemActive);
  200. m_TimerItemActive.RemoveAll();
  201. return true;
  202. }
  203. //删除空闲定时器
  204. bool CTimerEngine::KillAllFreeTimer()
  205. {
  206. //锁定资源
  207. CWHDataLocker lock(m_CriticalSection);//
  208. //清理内存
  209. tagTimerItem * pTimerItem = NULL;
  210. for (int i = 0; i < m_TimerItemFree.GetCount(); i++)
  211. {
  212. pTimerItem = m_TimerItemFree[i];
  213. ASSERT(pTimerItem != NULL);
  214. SafeDelete(pTimerItem);
  215. }
  216. m_TimerItemFree.RemoveAll();
  217. return true;
  218. }
  219. //设置接口
  220. bool CTimerEngine::SetTimerEngineEvent(IUnknownEx * pIUnknownEx)
  221. {
  222. //效验参数
  223. ASSERT(pIUnknownEx != NULL);
  224. ASSERT(m_bService == false);
  225. if (m_bService == true) return false;
  226. if (pIUnknownEx == NULL) return false;
  227. //设置接口
  228. ASSERT(pIUnknownEx != NULL);
  229. m_pIQueueServiceSink = QUERY_OBJECT_PTR_INTERFACE(pIUnknownEx, IQueueServiceSink);
  230. ASSERT(m_pIQueueServiceSink != NULL);
  231. return (m_pIQueueServiceSink != NULL);
  232. }
  233. //定时器通知
  234. void CTimerEngine::OnTimerThreadSink(DWORD dwNow)
  235. {
  236. //缓冲锁定
  237. CWHDataLocker lock(m_CriticalSection);//
  238. //查询定时器
  239. tagTimerItem * pTimerItem = NULL;
  240. for (INT_PTR i = m_TimerItemActive.GetCount() - 1; i >= 0; i--)
  241. {
  242. //效验参数
  243. pTimerItem = m_TimerItemActive[i];
  244. ASSERT(pTimerItem != NULL);
  245. if (pTimerItem == NULL) continue;
  246. //ASSERT(pTimerItem->dwTimeLeave > 0);
  247. //定时器处理
  248. bool bKillTimer = false;
  249. //pTimerItem->dwTimeLeave -= TIMER_SPACE;
  250. //if (pTimerItem->dwTimeLeave < TIMER_SPACE)
  251. if (CalSubTime(pTimerItem->dwTimeStart, dwNow) >= pTimerItem->dwElapse)
  252. {
  253. try
  254. {
  255. // BYTE cbBuffer[MAX_ASYNCHRONISM_DATA] = { 0 }; //接收缓冲
  256. //投递消息
  257. NTY_TimerEvent TimerEvent;
  258. TimerEvent.dwTimerID = pTimerItem->wTimerID;
  259. TimerEvent.dwBindParameter = pTimerItem->wBindParam;
  260. //magiii 12/04/09/ 先删除,再处理,不然如果在处理的过程中有settimer,会有问题
  261. //设置次数
  262. if (pTimerItem->dwRepeatTimes != TIMES_INFINITY)
  263. {
  264. ASSERT(pTimerItem->dwRepeatTimes > 0);
  265. pTimerItem->dwRepeatTimes--;
  266. if (pTimerItem->dwRepeatTimes == 0L)
  267. {
  268. bKillTimer = true;
  269. m_TimerItemActive.RemoveAt(i);
  270. m_TimerItemFree.Add(pTimerItem);
  271. }
  272. }
  273. m_pIQueueServiceSink->OnQueueServiceSink(EVENT_TIMER, &TimerEvent, sizeof(NTY_TimerEvent));
  274. }
  275. catch (...) {}
  276. //设置时间
  277. if (bKillTimer == false)//提前20个粒度进行通知 - TIMER_SPACE * 20
  278. {
  279. //if (pTimerItem->dwRepeatTimes == 1)
  280. // pTimerItem->dwTimeLeave = __max(TIMER_SPACE, pTimerItem->dwElapse - TIMER_SPACE * 10);
  281. //else
  282. // pTimerItem->dwTimeLeave = pTimerItem->dwElapse;
  283. pTimerItem->dwTimeStart = ::timeGetTime();
  284. }
  285. }
  286. }
  287. }
  288. //////////////////////////////////////////////////////////////////////////
  289. //建立对象函数
  290. extern "C" __declspec(dllexport) void * __cdecl CreateTimerEngine(const GUID & Guid, DWORD dwInterfaceVer)
  291. {
  292. //建立对象
  293. CTimerEngine * pTimerEngine = NULL;
  294. try
  295. {
  296. pTimerEngine = new CTimerEngine();
  297. if (pTimerEngine == NULL) throw TEXT("创建失败");
  298. void * pObject = pTimerEngine->QueryInterface(Guid, dwInterfaceVer);
  299. if (pObject == NULL) throw TEXT("接口查询失败");
  300. return pObject;
  301. }
  302. catch (...) {}
  303. //清理对象
  304. SafeDelete(pTimerEngine);
  305. return NULL;
  306. }
  307. //////////////////////////////////////////////////////////////////////////
  308. DWORD CTimerEngine::CalSubTime(DWORD timeStart, DWORD timeEnd)
  309. {
  310. if (timeEnd < timeStart)
  311. return ((DWORD)0XFFFFFFFF - timeStart) + timeEnd;
  312. else
  313. return timeEnd - timeStart;
  314. }
  315. //////////////////////////////////////////////////////////////////////////