Event.h 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530
  1. /*
  2. * Copyright: JessMA Open Source (ldcsaa@gmail.com)
  3. *
  4. * Author : Bruce Liang
  5. * Website : https://github.com/ldcsaa
  6. * Project : https://github.com/ldcsaa/HP-Socket
  7. * Blog : http://www.cnblogs.com/ldcsaa
  8. * Wiki : http://www.oschina.net/p/hp-socket
  9. * QQ Group : 44636872, 75375912
  10. *
  11. * Licensed under the Apache License, Version 2.0 (the "License");
  12. * you may not use this file except in compliance with the License.
  13. * You may obtain a copy of the License at
  14. *
  15. * http://www.apache.org/licenses/LICENSE-2.0
  16. *
  17. * Unless required by applicable law or agreed to in writing, software
  18. * distributed under the License is distributed on an "AS IS" BASIS,
  19. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  20. * See the License for the specific language governing permissions and
  21. * limitations under the License.
  22. */
  23. #pragma once
  24. #include "../hpsocket/GlobalDef.h"
  25. #include "Singleton.h"
  26. #include "FuncHelper.h"
  27. #include "PollHelper.h"
  28. #include <errno.h>
  29. #include <fcntl.h>
  30. #include <unistd.h>
  31. #include <sys/eventfd.h>
  32. #include <sys/timerfd.h>
  33. #include <sys/signalfd.h>
  34. class CPipeEvent
  35. {
  36. public:
  37. enum
  38. {
  39. EVT_1 = 0x01,
  40. EVT_WAKEUP = EVT_1,
  41. EVT_EXIT = 0x7F,
  42. EVT_SIG_0 = 0x80,
  43. EVT_SIG_MAX = EVT_SIG_0 + _NSIG,
  44. };
  45. public:
  46. int Wait(long lTimeout = INFINITE, const sigset_t* pSigSet = nullptr)
  47. {
  48. pollfd pfd = {m_fd[0], POLLIN};
  49. while(TRUE)
  50. {
  51. int rs = (int)::PollForSingleObject(pfd, lTimeout, pSigSet);
  52. if(rs <= TIMEOUT) return rs;
  53. if(pfd.revents & POLLIN)
  54. {
  55. BYTE v;
  56. if(!Get(v))
  57. return HAS_ERROR;
  58. if(v == 0)
  59. continue;
  60. return (int)v;
  61. }
  62. if(pfd.revents & _POLL_ALL_ERROR_EVENTS)
  63. {
  64. ::SetLastError(ERROR_BROKEN_PIPE);
  65. return HAS_ERROR;
  66. }
  67. ASSERT(FALSE);
  68. }
  69. }
  70. BOOL Set(BYTE bVal = EVT_WAKEUP)
  71. {
  72. ASSERT_CHECK_EINVAL(bVal != 0);
  73. return VERIFY(write(m_fd[1], &bVal, 1) > 0);
  74. }
  75. BOOL Get(BYTE& v)
  76. {
  77. ASSERT(IsValid());
  78. int rs = (int)read(m_fd[0], &v, 1);
  79. if(IS_HAS_ERROR(rs))
  80. {
  81. if(IS_WOULDBLOCK_ERROR())
  82. v = 0;
  83. else
  84. return FALSE;
  85. }
  86. else if(rs == 0)
  87. {
  88. ::SetLastError(ERROR_BROKEN_PIPE);
  89. return FALSE;
  90. }
  91. return TRUE;
  92. }
  93. BOOL Reset()
  94. {
  95. BYTE v;
  96. while(TRUE)
  97. {
  98. if(!Get(v))
  99. return FALSE;
  100. if(v == 0)
  101. break;
  102. }
  103. return TRUE;
  104. }
  105. BOOL SetSignal(BYTE bSigVal)
  106. {
  107. ASSERT_CHECK_EINVAL(bSigVal > 0 && bSigVal < _NSIG);
  108. return Set((BYTE)(EVT_SIG_0 + bSigVal));
  109. }
  110. static inline BYTE ToSignalValue(int iWaitResult)
  111. {
  112. if(iWaitResult <= EVT_SIG_0 || iWaitResult >= EVT_SIG_MAX)
  113. return 0;
  114. return (BYTE)(iWaitResult - EVT_SIG_0);
  115. }
  116. BOOL IsValid() {return IS_VALID_FD(m_fd[0]) && IS_VALID_FD(m_fd[1]);}
  117. operator FD () {return m_fd[0];}
  118. FD GetFD () {return m_fd[0];}
  119. public:
  120. CPipeEvent()
  121. {
  122. VERIFY_IS_NO_ERROR(pipe2(m_fd, O_NONBLOCK | O_CLOEXEC));
  123. VERIFY(::fcntl_SETFL(m_fd[0], O_NOATIME));
  124. VERIFY(::fcntl_SETFL(m_fd[1], O_NOATIME));
  125. }
  126. ~CPipeEvent()
  127. {
  128. close(m_fd[1]);
  129. close(m_fd[0]);
  130. }
  131. DECLARE_NO_COPY_CLASS(CPipeEvent)
  132. private:
  133. FD m_fd[2] = {INVALID_FD, INVALID_FD};
  134. };
  135. template<bool is_sem_mode = false> class CCounterEvent
  136. {
  137. public:
  138. eventfd_t Wait(long lTimeout = INFINITE, const sigset_t* pSigSet = nullptr)
  139. {
  140. pollfd pfd = {m_evt, POLLIN};
  141. while(TRUE)
  142. {
  143. long rs = ::PollForSingleObject(pfd, lTimeout, pSigSet);
  144. if(rs <= TIMEOUT) return (eventfd_t)rs;
  145. if(pfd.revents & POLLIN)
  146. {
  147. eventfd_t v;
  148. if(!Get(v))
  149. return HAS_ERROR;
  150. if(v == 0)
  151. continue;
  152. return v;
  153. }
  154. if(pfd.revents & _POLL_ALL_ERROR_EVENTS)
  155. {
  156. ::SetLastError(ERROR_HANDLES_CLOSED);
  157. return HAS_ERROR;
  158. }
  159. ASSERT(FALSE);
  160. }
  161. }
  162. BOOL Set(eventfd_t val = 1)
  163. {
  164. ASSERT_CHECK_EINVAL(val > 0);
  165. int rs = eventfd_write(m_evt, val);
  166. return VERIFY_IS_NO_ERROR(rs);
  167. }
  168. BOOL Get(eventfd_t& v)
  169. {
  170. ASSERT(IsValid());
  171. if(IS_HAS_ERROR(eventfd_read(m_evt, &v)))
  172. {
  173. if(IS_WOULDBLOCK_ERROR())
  174. v = 0;
  175. else
  176. return FALSE;
  177. }
  178. return TRUE;
  179. }
  180. BOOL Reset()
  181. {
  182. eventfd_t v;
  183. while(TRUE)
  184. {
  185. if(!Get(v))
  186. return FALSE;
  187. if(v == 0)
  188. break;
  189. }
  190. return TRUE;
  191. }
  192. BOOL IsValid() {return IS_VALID_FD(m_evt);}
  193. operator FD () {return m_evt;}
  194. FD GetFD () {return m_evt;}
  195. public:
  196. CCounterEvent(int iInitCount = 0)
  197. {
  198. int iFlag = EFD_NONBLOCK | EFD_CLOEXEC | (is_sem_mode ? EFD_SEMAPHORE : 0);
  199. m_evt = eventfd(iInitCount, iFlag);
  200. VERIFY(IsValid());
  201. }
  202. ~CCounterEvent()
  203. {
  204. if(IsValid()) close(m_evt);
  205. }
  206. DECLARE_NO_COPY_CLASS(CCounterEvent)
  207. private:
  208. FD m_evt = INVALID_FD;
  209. };
  210. using CSimpleEvent = CCounterEvent<false>;
  211. using CSemaphoreEvent = CCounterEvent<true>;
  212. using CEvt = CSimpleEvent;
  213. class CTimerEvent
  214. {
  215. public:
  216. ULLONG Wait(long lTimeout = INFINITE, const sigset_t* pSigSet = nullptr)
  217. {
  218. pollfd pfd = {m_tmr, POLLIN};
  219. while(TRUE)
  220. {
  221. SSIZE_T rs = ::PollForSingleObject(pfd, lTimeout, pSigSet);
  222. if(rs <= TIMEOUT) return (ULLONG)rs;
  223. if(pfd.revents & POLLIN)
  224. {
  225. BOOL ok;
  226. ULLONG v;
  227. if(!Get(v, ok))
  228. return HAS_ERROR;
  229. if(!ok)
  230. continue;
  231. return v;
  232. }
  233. if(pfd.revents & _POLL_ALL_ERROR_EVENTS)
  234. {
  235. ::SetLastError(ERROR_HANDLES_CLOSED);
  236. return HAS_ERROR;
  237. }
  238. ASSERT(FALSE);
  239. }
  240. }
  241. BOOL Set(LLONG llInterval, LLONG llStart = -1)
  242. {
  243. ASSERT_CHECK_EINVAL(llInterval >= 0L);
  244. if(llStart < 0)
  245. llStart = llInterval;
  246. itimerspec its;
  247. ::MillisecondToTimespec(llStart, its.it_value);
  248. ::MillisecondToTimespec(llInterval, its.it_interval);
  249. int rs = timerfd_settime(m_tmr, 0, &its, nullptr);
  250. return VERIFY_IS_NO_ERROR(rs);
  251. }
  252. BOOL Get(ULLONG &v, BOOL& ok)
  253. {
  254. ASSERT(IsValid());
  255. return ::ReadTimer(m_tmr, &v, &ok);
  256. }
  257. BOOL Reset()
  258. {
  259. BOOL ok;
  260. ULLONG v;
  261. while(TRUE)
  262. {
  263. if(!Get(v, ok))
  264. return FALSE;
  265. if(!ok)
  266. break;
  267. }
  268. return TRUE;
  269. }
  270. BOOL GetTime(LLONG& lStart, LLONG& lInterval)
  271. {
  272. itimerspec its;
  273. if(IS_HAS_ERROR(timerfd_gettime(m_tmr, &its)))
  274. return FALSE;
  275. lStart = ::TimespecToMillisecond(its.it_value);
  276. lInterval = ::TimespecToMillisecond(its.it_interval);
  277. return TRUE;
  278. }
  279. BOOL IsValid() {return IS_VALID_FD(m_tmr);}
  280. operator FD () {return m_tmr;}
  281. FD GetFD () {return m_tmr;}
  282. public:
  283. CTimerEvent(bool bRealTimeClock = FALSE)
  284. {
  285. int iCID = (bRealTimeClock ? CLOCK_REALTIME : CLOCK_MONOTONIC);
  286. m_tmr = timerfd_create(iCID, TFD_NONBLOCK | TFD_CLOEXEC);
  287. VERIFY(IsValid());
  288. }
  289. ~CTimerEvent()
  290. {
  291. if(IsValid()) close(m_tmr);
  292. }
  293. DECLARE_NO_COPY_CLASS(CTimerEvent)
  294. private:
  295. FD m_tmr = INVALID_FD;
  296. };
  297. class CSignalEvent
  298. {
  299. public:
  300. int Wait(signalfd_siginfo& sgInfo, long lTimeout = INFINITE, const sigset_t* pSigSet = nullptr)
  301. {
  302. m_dwTID = SELF_THREAD_ID;
  303. pollfd pfd = {m_sig, POLLIN};
  304. while(TRUE)
  305. {
  306. long rs = ::PollForSingleObject(pfd, lTimeout, pSigSet);
  307. if(rs <= TIMEOUT) return (int)rs;
  308. if(pfd.revents & POLLIN)
  309. {
  310. BOOL ok;
  311. if(!Get(sgInfo, ok))
  312. return HAS_ERROR;
  313. if(!ok)
  314. continue;
  315. return sgInfo.ssi_signo;
  316. }
  317. if(pfd.revents & _POLL_ALL_ERROR_EVENTS)
  318. {
  319. ::SetLastError(ERROR_HANDLES_CLOSED);
  320. return HAS_ERROR;
  321. }
  322. ASSERT(FALSE);
  323. }
  324. m_dwTID = 0;
  325. }
  326. BOOL Set(int iSig, const sigval sgVal, THR_ID dwTID = 0)
  327. {
  328. if(dwTID == 0)
  329. {
  330. dwTID = m_dwTID;
  331. if(dwTID == 0)
  332. {
  333. ::SetLastError(ERROR_INVALID_STATE);
  334. return FALSE;
  335. }
  336. }
  337. #if !defined(__ANDROID__)
  338. int rs = pthread_sigqueue(dwTID, iSig, sgVal);
  339. #else
  340. int rs = pthread_kill(dwTID, iSig);
  341. #endif
  342. return IS_NO_ERROR(rs);
  343. }
  344. BOOL Get(signalfd_siginfo& v, BOOL& ok)
  345. {
  346. ASSERT(IsValid());
  347. static const SSIZE_T SIZE = sizeof(signalfd_siginfo);
  348. if(read(m_sig, &v, SIZE) == SIZE)
  349. ok = TRUE;
  350. {
  351. if(IS_WOULDBLOCK_ERROR())
  352. ok = FALSE;
  353. else
  354. return FALSE;
  355. }
  356. return ok;
  357. }
  358. BOOL Reset()
  359. {
  360. BOOL ok;
  361. signalfd_siginfo v;
  362. while(TRUE)
  363. {
  364. if(!Get(v, ok))
  365. return FALSE;
  366. if(!ok)
  367. break;
  368. }
  369. return TRUE;
  370. }
  371. BOOL Mask(const sigset_t* pSigMask)
  372. {
  373. if(!pSigMask)
  374. {
  375. if(!IsValid()) return TRUE;
  376. return IS_NO_ERROR(close(m_sig));
  377. }
  378. FD sig = signalfd(m_sig, pSigMask, SFD_NONBLOCK | SFD_CLOEXEC);
  379. if(IS_VALID_FD(sig))
  380. {
  381. m_sig = sig;
  382. return TRUE;
  383. }
  384. return FALSE;
  385. }
  386. BOOL IsValid() {return IS_VALID_FD(m_sig);}
  387. operator FD () {return m_sig;}
  388. FD GetFD () {return m_sig;}
  389. public:
  390. CSignalEvent(const sigset_t* pSigMask = nullptr)
  391. {
  392. if(pSigMask) VERIFY(Mask(pSigMask));
  393. }
  394. ~CSignalEvent()
  395. {
  396. if(IsValid()) close(m_sig);
  397. }
  398. DECLARE_NO_COPY_CLASS(CSignalEvent)
  399. private:
  400. FD m_sig = INVALID_FD;
  401. THR_ID m_dwTID = 0;
  402. };