evtpoll.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854
  1. #include <assert.h>
  2. #include <errno.h>
  3. #include "memutil.h"
  4. #include "spinlock.h"
  5. #include "list.h"
  6. #include "array.h"
  7. #include "refcnt.h"
  8. #include "evtpoll.h"
  9. #include "core.h"
  10. #include "queue.h"
  11. #include <winpr/wlog.h>
  12. #define TAG TOOLKIT_TAG("evtpoll")
  13. #ifndef _WIN32
  14. #include <unistd.h>
  15. struct event_epoll_data_s {
  16. int type;
  17. int fd;
  18. void* owner;
  19. };
  20. struct event_epoll_s {
  21. int fd;
  22. /*insterest*/
  23. spinlock_t interest_list_lock;
  24. struct list_head interest_list;
  25. /*new mechanism*/
  26. event_epoll_data_t** interests;
  27. unsigned int cnt_of_intersests;
  28. unsigned int nfds;
  29. };
  30. struct evtpoll_interest_entry_s {
  31. struct list_head entry;
  32. //int type;
  33. int events;
  34. int pending;
  35. //void* key;
  36. void* data;
  37. spinlock_t lock;
  38. struct evtpoll_interest_s* owner;
  39. };
  40. struct evtpoll_interest_s {
  41. struct list_head node; // for evtpoll_t::interest_list
  42. struct list_head entry_list; //no used
  43. int fd;
  44. int events;
  45. int type; //no used
  46. evtpoll_t* owner;
  47. array_header_t* entries;
  48. spinlock_t lock;
  49. volatile int entry_counts;
  50. };
  51. typedef struct evtpoll_interest_entry_s evtpoll_interest_entry_t;
  52. typedef struct evtpoll_interest_s evtpoll_interest_t;
  53. static int evtpoll__interest_empty(evtpoll_t* ep)
  54. {
  55. int ret;
  56. assert(ep);
  57. spinlock_enter(&ep->interest_list_lock, -1);
  58. ret = list_empty(&ep->interest_list);
  59. spinlock_leave(&ep->interest_list_lock);
  60. return ret;
  61. }
  62. event_epoll_data_t* evtpoll_data_new()
  63. {
  64. event_epoll_data_t* data = ZALLOC_T(event_epoll_data_t);
  65. return data;
  66. }
  67. void evtpoll_data_destroy(event_epoll_data_t* epoll_data)
  68. {
  69. if (epoll_data) {
  70. free(epoll_data);
  71. }
  72. }
  73. int evtpoll_data_set(event_epoll_data_t* epoll_data, int type, int fd, void* data)
  74. {
  75. assert(epoll_data);
  76. epoll_data->fd = fd;
  77. epoll_data->type = type;
  78. epoll_data->owner = data;
  79. return 0;
  80. }
  81. int evtpoll_data_get_fd(const event_epoll_data_t* const epoll_data)
  82. {
  83. assert(epoll_data);
  84. return epoll_data->fd;
  85. }
  86. int evtpoll_data_get_type(const event_epoll_data_t* const epoll_data)
  87. {
  88. assert(epoll_data);
  89. return epoll_data->type;
  90. }
  91. void evtpoll_data_set_data(event_epoll_data_t* epoll_data, void* data)
  92. {
  93. assert(epoll_data);
  94. epoll_data->owner = data;
  95. }
  96. void* evtpoll_data_get_data(const event_epoll_data_t* const epoll_data)
  97. {
  98. assert(epoll_data);
  99. return epoll_data->owner;
  100. }
  101. static unsigned int next_power_of_two(unsigned int val) {
  102. val -= 1;
  103. val |= val >> 1;
  104. val |= val >> 2;
  105. val |= val >> 4;
  106. val |= val >> 8;
  107. val |= val >> 16;
  108. val += 1;
  109. return val;
  110. }
  111. static void resize_interests_capacity(evtpoll_t*ep, int len)
  112. {
  113. event_epoll_data_t** interests;
  114. void* fake_interest_list;
  115. void* fake_interest_count;
  116. unsigned int cnt_of_intersests;
  117. unsigned int i;
  118. if (len <= ep->cnt_of_intersests)
  119. return;
  120. /* Preserve fake interest list and count at the end of the interests */
  121. if (ep->interests != NULL) {
  122. fake_interest_list = ep->interests[ep->cnt_of_intersests];
  123. fake_interest_count = ep->interests[ep->cnt_of_intersests + 1];
  124. }
  125. else {
  126. fake_interest_list = NULL;
  127. fake_interest_count = NULL;
  128. }
  129. cnt_of_intersests = next_power_of_two(len + 2) - 2;
  130. interests = REALLOC(ep->interests, (cnt_of_intersests + 2) * sizeof(ep->interests[0]));
  131. if (interests == NULL) {
  132. WLog_ERR(TAG, "no enough memory!!");
  133. abort();
  134. }
  135. for (i = ep->cnt_of_intersests; i < cnt_of_intersests; i++)
  136. interests[i] = NULL;
  137. interests[cnt_of_intersests] = fake_interest_list;
  138. interests[cnt_of_intersests + 1] = fake_interest_count;
  139. ep->interests = interests;
  140. ep->cnt_of_intersests = cnt_of_intersests;
  141. }
  142. void evtpoll__add(evtpoll_t* ep, event_epoll_data_t* evtpoll_data)
  143. {
  144. resize_interests_capacity(ep, evtpoll_data->fd + 1);
  145. if (ep->interests[evtpoll_data->fd] == NULL) {
  146. ep->interests[evtpoll_data->fd] = evtpoll_data;
  147. }
  148. }
  149. evtpoll_t* evtpoll_create()
  150. {
  151. int fd;
  152. evtpoll_t* ep = ZALLOC_T(evtpoll_t);
  153. if (!ep)
  154. return NULL;
  155. /*
  156. since Linux 2.6.8 the argument is ignored but must be g0 for compatibility,
  157. bcz kernel would allocate space dynamically.
  158. */
  159. fd = epoll_create1(EPOLL_CLOEXEC);
  160. if (fd == -1 && (errno == ENOSYS || errno == EINVAL)) {
  161. fd = epoll_create(MAX_EPOLL_EVENT);
  162. if (fd != -1) {
  163. make_fd_cloexec(fd, 1);
  164. }
  165. }
  166. if (fd == -1) {
  167. WLog_ERR(TAG, "epoll fd create failed: %d", (errno));
  168. goto on_error;
  169. }
  170. ep->fd = fd;
  171. spinlock_init(&ep->interest_list_lock);
  172. INIT_LIST_HEAD(&ep->interest_list);
  173. ep->cnt_of_intersests = 0;
  174. ep->interests = NULL;
  175. ep->nfds = 0;
  176. return ep;
  177. on_error:
  178. free(ep);
  179. return NULL;
  180. }
  181. int evtpoll_get_epoll_fd(const evtpoll_t* const evt_poll)
  182. {
  183. return evt_poll->fd;
  184. }
  185. int evtpoll_get_raw_fd(evtpoll_t* ep)
  186. {
  187. return ep->fd;
  188. }
  189. void evtpoll__interest_entry_set(
  190. evtpoll_interest_entry_t* entry,
  191. int events,
  192. int type,
  193. int pending,
  194. void* key,
  195. void* data)
  196. {
  197. assert(entry);
  198. assert(entry->owner);
  199. //entry->type = type;
  200. entry->events = events;
  201. entry->data = data;
  202. entry->pending = pending;
  203. //entry->key = key;
  204. }
  205. void evtpoll__interest_entry_reset(evtpoll_interest_entry_t* entry) {
  206. evtpoll__interest_entry_set(entry, 0, 0, 0, NULL, NULL);
  207. }
  208. static evtpoll_interest_entry_t* evtpoll__interest_entry_create(evtpoll_interest_t* interest)
  209. {
  210. evtpoll_interest_entry_t* entry = MALLOC_T(evtpoll_interest_entry_t);
  211. assert(entry);
  212. entry->owner = interest;
  213. evtpoll__interest_entry_reset(entry);
  214. spinlock_init(&entry->lock);
  215. return entry;
  216. }
  217. static int evtpoll__interest_entry_is_ready(const evtpoll_interest_entry_t* const entry)
  218. {
  219. if (entry->pending != 0) {
  220. return 0;
  221. }
  222. if (!entry->data) {
  223. return 0;
  224. }
  225. if (entry->events == 0) {
  226. return 0;
  227. }
  228. return 1;
  229. }
  230. void evtpoll__interest_entry_destroy(evtpoll_interest_entry_t* entry)
  231. {
  232. free(entry);
  233. }
  234. void evtpoll__interest_lock(evtpoll_interest_t* interest)
  235. {
  236. spinlock_enter(&interest->lock, 0);
  237. }
  238. void evtpoll__interest_unlock(evtpoll_interest_t* interest)
  239. {
  240. spinlock_leave(&interest->lock);
  241. }
  242. void evtpoll___add_interest_list(evtpoll_interest_t* inst)
  243. {
  244. evtpoll_t* ep = inst->owner;
  245. assert(ep);
  246. spinlock_enter(&ep->interest_list_lock, -1);
  247. list_add(&inst->node, &ep->interest_list);
  248. spinlock_leave(&ep->interest_list_lock);
  249. }
  250. void evtpoll___del_interest_list(evtpoll_interest_t* inst)
  251. {
  252. evtpoll_t* ep = inst->owner;
  253. assert(ep);
  254. spinlock_enter(&ep->interest_list_lock, -1);
  255. list_del(&inst->node);
  256. inst->node.next = inst->node.prev = NULL;
  257. spinlock_leave(&ep->interest_list_lock);
  258. }
  259. /*remove from inst list*/
  260. void evtpoll__interest_free(evtpoll_interest_t* inst)
  261. {
  262. evtpoll___del_interest_list(inst);
  263. }
  264. static int evtpoll__ctl(evtpoll_t* ep, int event_mask, int ctrl_mod, int fd, evtpoll_interest_t* inst)
  265. {
  266. int ret = -1;
  267. struct epoll_event ee;
  268. assert(ep);
  269. ee.events = event_mask;
  270. if (inst) {
  271. ee.data.ptr = inst;
  272. }
  273. else {//data is union type.
  274. ee.data.fd = fd;
  275. }
  276. ret = epoll_ctl(evtpoll_get_epoll_fd(ep), ctrl_mod, fd, &ee);
  277. if (ret == -1) {
  278. WLog_ERR(TAG, "epoll ctl failed: %d", (errno));
  279. }
  280. else {
  281. WLog_INFO(TAG, "epoll_ctl(%d): OUT:%d, IN:%d, OTHERS:0x%08X, ADD:%d, MOD:%d, inst:0x%X ret:%d",
  282. fd,
  283. (event_mask & EPOLLOUT) > 0 ? 1 : 0, (event_mask & EPOLLIN) > 0 ? 1 : 0,
  284. (event_mask & ~(EPOLLOUT | EPOLLIN)),
  285. ctrl_mod == EPOLL_CTL_ADD ? 1 : 0, ctrl_mod == EPOLL_CTL_MOD ? 1 : 0, inst, ret);
  286. }
  287. return ret;
  288. }
  289. /*no use for now.*/
  290. //static int evtpoll__ctl_remove(evtpoll_t* ep, int event_mask, int fd, void* data)
  291. //{
  292. // int ret = -1;
  293. // struct epoll_event ee;
  294. // ee.events = event_mask;
  295. // if (data)
  296. // ee.data.ptr = data;
  297. // else
  298. // ee.data.fd = fd;
  299. // ret = epoll_ctl(ep->fd, EPOLL_CTL_DEL, fd, &ee);
  300. // if (ret == 0 || (ret == -1 && errno == ENOENT)) {
  301. // return 0;
  302. // }
  303. // WLog_ERR(TAG, "epoll remove ctrl failed: %d", (errno));
  304. // return -1;
  305. //}
  306. /*!
  307. * @brief
  308. one 'evtpoll_interest_t' maps to one fd.
  309. each interest instance has {DEFAULT_INTEREST_OP_COUNT} evtpoll_interest_entry_t type object.
  310. * @param[in]
  311. * @return : SUCC: new evtpoll_interest_t type pointer object; NULL: failed
  312. */
  313. static evtpoll_interest_t* evtpoll__interest_create(int fd)
  314. {
  315. int i;
  316. evtpoll_interest_t* inst = ZALLOC_T(evtpoll_interest_t);
  317. if (!inst) {
  318. return NULL;
  319. }
  320. inst->fd = fd;
  321. INIT_LIST_HEAD(&inst->entry_list);
  322. inst->entry_counts = 0;
  323. inst->owner = NULL;
  324. inst->type = 0;
  325. inst->events = 0;
  326. inst->entries = array_make(DEFAULT_INTEREST_OP_COUNT, sizeof(evtpoll_interest_entry_t*));
  327. for (i = 0; i < DEFAULT_INTEREST_OP_COUNT; ++i) {
  328. ARRAY_IDX(inst->entries, i, evtpoll_interest_entry_t*) = evtpoll__interest_entry_create(inst);
  329. }
  330. return inst;
  331. }
  332. /*free inst and its entry*/
  333. static void evtpoll__interest_destroy(evtpoll_interest_t* inst)
  334. {
  335. int i;
  336. assert(inst);
  337. assert(list_empty(&inst->entry_list));
  338. for (i = 0; i < inst->entries->nelts; ++i)
  339. evtpoll__interest_entry_destroy(ARRAY_IDX(inst->entries, i, evtpoll_interest_entry_t*));
  340. array_free(inst->entries);
  341. free(inst);
  342. }
  343. static evtpoll_interest_t* evtpoll__find_interest(const evtpoll_t* const cst_ep, int fd)
  344. {
  345. struct list_head* pos;
  346. struct list_head* tmp;
  347. if (list_empty(&cst_ep->interest_list))
  348. return NULL;
  349. list_for_each_safe(pos, tmp, &cst_ep->interest_list) {
  350. evtpoll_interest_t* node = list_entry(pos, evtpoll_interest_t, node);
  351. if (node->fd == fd) {
  352. return node;
  353. }
  354. }
  355. return NULL;
  356. }
  357. static void evtpoll__interest_clear(evtpoll_t* ep)
  358. {
  359. struct list_head* pos;
  360. struct list_head* tmp;
  361. if (list_empty(&ep->interest_list))
  362. return;
  363. spinlock_enter(&ep->interest_list_lock, -1);
  364. list_for_each_safe(pos, tmp, &ep->interest_list) {
  365. evtpoll_interest_t* node = list_entry(pos, evtpoll_interest_t, node);
  366. list_del(pos);
  367. if (node->events != 0) {
  368. evtpoll_unsubscribe(node->owner, EV_READ_WRITE_WITH_LT_PURE, node->fd, 0, NULL, NULL);
  369. }
  370. evtpoll__interest_destroy(node);
  371. }
  372. spinlock_leave(&ep->interest_list_lock);
  373. return;
  374. }
  375. static int evtpoll__register_interest(evtpoll_t* ep, evtpoll_interest_t* inst)
  376. {
  377. int ret = -1;
  378. assert(ep);
  379. assert(inst);
  380. evtpoll_interest_t* exist;
  381. #if 1
  382. //×¢²áºó²»Á¢¼´½øÐмàÌý
  383. ret = 0;
  384. #else
  385. ret = evtpoll__ctl(ep, EV_READ_WRITE_WITH_LT_FULL, EPOLL_CTL_ADD, inst->fd, NULL);
  386. if (ret != 0)
  387. return ret;
  388. #endif
  389. evtpoll___add_interest_list(inst);
  390. #if 1 //DEBUG
  391. exist = evtpoll__find_interest(ep, inst->fd);
  392. assert(exist);
  393. assert(exist == inst);
  394. #endif
  395. return ret;
  396. }
  397. static void evtpoll__unregister_interest(evtpoll_interest_t* inst)
  398. {
  399. evtpoll__interest_free(inst);
  400. evtpoll__interest_destroy(inst);
  401. }
  402. /*remove inst from list and destroy it*/
  403. //static int evtpoll__unregister_interest(evtpoll_t* ep, int fd)
  404. //{
  405. // int ret = 0;
  406. // evtpoll_interest_t* exist;
  407. // exist = evtpoll__find_interest(ep, fd);
  408. // if (exist) {
  409. // evtpoll__unregister_interest(exist);
  410. // }
  411. // return ret;
  412. //}
  413. int evtpoll_attach(evtpoll_t* ep, int interest_fd)
  414. {
  415. int ret = 0;
  416. assert(interest_fd > 0);
  417. evtpoll_interest_t* exist;
  418. WLog_DBG(TAG, "==> attach interest fd(%d) ", interest_fd);
  419. exist = evtpoll__find_interest(ep, interest_fd);
  420. if (exist) {
  421. WLog_WARN(TAG, "detect interest fd %d already exist.", interest_fd);
  422. return -1;
  423. }
  424. exist = evtpoll__interest_create(interest_fd);
  425. if (!exist) {
  426. WLog_ERR(TAG, "create epueue insterest fd %d failed!", interest_fd);
  427. return -1;
  428. }
  429. exist->owner = ep;
  430. ret = evtpoll__register_interest(ep, exist);
  431. if (ret != 0) {
  432. evtpoll__interest_destroy(exist);
  433. return -1;
  434. }
  435. WLog_DBG(TAG, "<== normal attach interest fd(%d) succ.", interest_fd);
  436. return 0;
  437. }
  438. /*unsubscribe R|W event and unregist it */
  439. static void evtpoll__detach(evtpoll_interest_t* inst)
  440. {
  441. if (inst->events != 0) {
  442. evtpoll_unsubscribe(inst->owner, EV_READ_WRITE_WITH_LT_PURE, inst->fd, 0, NULL, NULL);
  443. }
  444. evtpoll__unregister_interest(inst);
  445. }
  446. void evtpoll_detach(evtpoll_t* ep, int interest_fd)
  447. {
  448. evtpoll_interest_t* exist;
  449. exist = evtpoll__find_interest(ep, interest_fd);
  450. if (exist) {
  451. evtpoll__detach(exist);
  452. }
  453. }
  454. static int evtpoll__subscribe_precheck(evtpoll_interest_entry_t* entry, int exist, void* data)
  455. {
  456. if (exist) {
  457. if (entry->pending) {
  458. WLog_ERR(TAG, "the entry is still pending...");
  459. return -1;
  460. }
  461. else if ((uintptr_t)entry->data == (uintptr_t)data) {
  462. WLog_WARN(TAG, "entry already exists and seems same, return previously.");
  463. return 0;
  464. }
  465. WLog_DBG(TAG, "data:0x%08X vs data:0x%08X", entry->data, data);
  466. }
  467. //if (data != NULL) {
  468. // const int io_type = ioqueue_overlapped_get_type(data);
  469. // WLog_INFO(TAG, "ioqueue ov type for subscribing: 0x%X", io_type);
  470. //}
  471. //else if (!entry->data) {
  472. // WLog_ERR(TAG, "no data data for event!");
  473. // return -1;
  474. //}
  475. return 1;
  476. }
  477. static int evtpoll__subscribe_read(evtpoll_t* ep, evtpoll_interest_t* inst, void* data)
  478. {
  479. int ret;
  480. int has = 0;
  481. int op = EPOLL_CTL_ADD;
  482. int events = EPOLLIN;
  483. evtpoll_interest_entry_t* entry;
  484. if (inst->events & EV_READ) {
  485. has = 1;
  486. }
  487. entry = ARRAY_IDX(inst->entries, EV_INTEREST_ENTRY_IN_IDX, evtpoll_interest_entry_t*);
  488. assert(entry);
  489. ret = evtpoll__subscribe_precheck(entry, has, data);
  490. if (ret < 1) {
  491. return ret;
  492. }
  493. ret = 0;
  494. if (has) {
  495. evtpoll__interest_entry_set(entry, EV_READ, 0, 0, NULL, data);
  496. WLog_INFO(TAG, "fd(%d): read entry existed, only update the ov and returned.", inst->fd);
  497. return 1;
  498. }
  499. if (inst->events & EV_WRITE) {
  500. op = EPOLL_CTL_MOD;
  501. events |= EPOLLOUT;
  502. }
  503. ret = evtpoll__ctl(ep, events, op, inst->fd, inst);
  504. if (ret) {
  505. WLog_ERR(TAG, "fd(%d): set read register failed !", inst->fd);
  506. }
  507. else {
  508. inst->events |= EV_READ;
  509. evtpoll__interest_entry_set(entry, EV_READ, 0, 0, NULL, data);
  510. }
  511. return ret;
  512. }
  513. static int evtpoll__unsubscribe_read(evtpoll_t* ep, evtpoll_interest_t* inst)
  514. {
  515. int ret;
  516. int events = EPOLLIN;
  517. int op = EPOLL_CTL_DEL;
  518. evtpoll_interest_entry_t* entry = NULL;
  519. if (!(inst->events & EV_READ)) {
  520. WLog_WARN(TAG, "read event is not existed");
  521. return 0;
  522. }
  523. if (inst->events & EV_WRITE) {
  524. op = EPOLL_CTL_MOD;
  525. events = EPOLLOUT;
  526. }
  527. ret = evtpoll__ctl(ep, events, op, inst->fd, inst);
  528. if (ret) {
  529. WLog_ERR(TAG, "un read register failed !");
  530. }
  531. else {
  532. inst->events &= ~(EV_READ);
  533. entry = ARRAY_IDX(inst->entries, EV_INTEREST_ENTRY_IN_IDX, evtpoll_interest_entry_t*);
  534. evtpoll__interest_entry_reset(entry);
  535. }
  536. return ret;
  537. }
  538. static int evtpoll__subscribe_write(evtpoll_t* ep, evtpoll_interest_t* inst, void* data)
  539. {
  540. int ret;
  541. //int io_type = -1;
  542. int has = 0;
  543. int op = EPOLL_CTL_ADD;
  544. int events = EPOLLOUT;
  545. evtpoll_interest_entry_t* entry = NULL;
  546. if (inst->events & EV_WRITE) {
  547. has = 1;
  548. }
  549. entry = ARRAY_IDX(inst->entries, EV_INTEREST_ENTRY_OUT_IDX, evtpoll_interest_entry_t*);
  550. assert(entry);
  551. ret = evtpoll__subscribe_precheck(entry, has, data);
  552. if (ret < 1) {
  553. return ret;
  554. }
  555. ret = 0;
  556. //io_type = ioqueue_overlapped_get_type(data);
  557. if (has) {
  558. evtpoll__interest_entry_set(entry, EV_WRITE, 0, 0, NULL, data);
  559. WLog_INFO(TAG, "fd(%d): write entry existed, only update the ov and returned.", inst->fd);
  560. return 1;
  561. }
  562. if (inst->events & EV_READ) {
  563. op = EPOLL_CTL_MOD;
  564. events |= EPOLLIN;
  565. }
  566. ret = evtpoll__ctl(ep, events, op, inst->fd, inst);
  567. if (ret) {
  568. WLog_ERR(TAG, "fd(%d): set write register failed !", inst->fd);
  569. }
  570. else {
  571. inst->events |= EV_WRITE;
  572. evtpoll__interest_entry_set(entry, EV_WRITE, 0, 0, NULL, data);
  573. }
  574. return ret;
  575. }
  576. static int evtpoll__unsubscribe_write(evtpoll_t* ep, evtpoll_interest_t* inst)
  577. {
  578. int ret;
  579. int events = EPOLLOUT;
  580. int op = EPOLL_CTL_DEL;
  581. if (!(inst->events & EV_WRITE)) {
  582. WLog_WARN(TAG, "write event is not existed");
  583. return 0;
  584. }
  585. if (inst->events & EV_READ) {
  586. op = EPOLL_CTL_MOD;
  587. events = EPOLLIN;
  588. }
  589. ret = evtpoll__ctl(ep, events, op, inst->fd, inst);
  590. if (ret) {
  591. WLog_ERR(TAG, "un read register failed !");
  592. }
  593. else {
  594. evtpoll_interest_entry_t* entry = ARRAY_IDX(inst->entries, EV_INTEREST_ENTRY_OUT_IDX, evtpoll_interest_entry_t*);
  595. evtpoll__interest_entry_reset(entry);
  596. inst->events &= ~(EV_WRITE);
  597. }
  598. return ret;
  599. }
  600. int evtpoll_subscribe(evtpoll_t* ep, int event_mask, int fd, void* rdata, void* wdata)
  601. {
  602. int ret = 0;
  603. evtpoll_interest_t* inst;
  604. inst = evtpoll__find_interest(ep, fd);
  605. if (!inst) {
  606. WLog_ERR(TAG, "the fd(%d) have not been registered", fd);
  607. return -1;
  608. }
  609. if (event_mask & EPOLLET) {
  610. WLog_WARN(TAG, "EPOLLET event type is not supported now.");
  611. event_mask &= ~EPOLLET;
  612. }
  613. if (event_mask & ~(EV_READ_WRITE_WITH_LT_PURE)) {
  614. WLog_ERR(TAG, "event type exclude read or write is not supported now.");
  615. return -1;
  616. }
  617. if (!ret && (event_mask & EV_READ)) {
  618. ret = evtpoll__subscribe_read(ep, inst, rdata);
  619. if (ret > 0) {
  620. WLog_WARN(TAG, "read event has been registered");
  621. ret = 0;
  622. }
  623. }
  624. if (!ret && (event_mask & EV_WRITE)) {
  625. ret = evtpoll__subscribe_write(ep, inst, wdata);
  626. if (ret > 0) {
  627. WLog_WARN(TAG, "write event has been registered");
  628. ret = 0;
  629. }
  630. }
  631. return ret;
  632. }
  633. int evtpoll_unsubscribe(evtpoll_t* ep, int event_mask, int fd, int only_reset, void** rdata, void** wdata)
  634. {
  635. int ret;
  636. evtpoll_interest_t* exist;
  637. exist = evtpoll__find_interest(ep, fd);
  638. if (!exist) {
  639. WLog_ERR(TAG, "the fd %d have not been registered", fd);
  640. return -1;
  641. }
  642. if (event_mask & ~(EV_READ_WRITE_WITH_LT_PURE)) {
  643. WLog_WARN(TAG, "event type exclude read or write is not supported now.");
  644. return -1;
  645. }
  646. ret = 0;
  647. if (!ret && (event_mask & EV_READ)) {
  648. evtpoll_interest_entry_t* entry =
  649. ARRAY_IDX(exist->entries, EV_INTEREST_ENTRY_IN_IDX, evtpoll_interest_entry_t*);
  650. if (rdata)
  651. *rdata = entry->data;
  652. if (only_reset) {
  653. evtpoll__interest_entry_reset(entry);
  654. }
  655. else {
  656. ret = evtpoll__unsubscribe_read(ep, exist);
  657. }
  658. }
  659. if (!ret && (event_mask & EV_WRITE)) {
  660. evtpoll_interest_entry_t* entry =
  661. ARRAY_IDX(exist->entries, EV_INTEREST_ENTRY_OUT_IDX, evtpoll_interest_entry_t*);
  662. if (wdata)
  663. *wdata = entry->data;
  664. if (only_reset) {
  665. evtpoll__interest_entry_reset(entry);
  666. }
  667. else {
  668. ret = evtpoll__unsubscribe_write(ep, exist);
  669. }
  670. }
  671. return ret;
  672. }
  673. static int evtpoll__deal_inner(evtpoll_interest_t* inst, int idx, void** data, int reset)
  674. {
  675. evtpoll_interest_entry_t* entry = ARRAY_IDX(inst->entries, idx, evtpoll_interest_entry_t*);
  676. assert(entry);
  677. if (evtpoll__interest_entry_is_ready(entry)) {
  678. WLog_DBG(TAG, "interest entry is ready.");
  679. *data = entry->data;
  680. if (reset) {
  681. evtpoll__interest_entry_reset(entry);
  682. }
  683. return 0;
  684. }
  685. WLog_WARN(TAG, "interest entry is not ready.");
  686. return -1;
  687. }
  688. int evtpoll_deal(evtpoll_t* ep, struct epoll_event* event, void** data, int cancel)
  689. {
  690. int ret = 0;
  691. evtpoll_interest_t* inst;
  692. evtpoll_interest_t* exist;
  693. if (!(event->events & (EPOLLIN | EPOLLOUT))) {
  694. WLog_DBG(TAG, "no event mask.");
  695. return -1;
  696. }
  697. inst = (evtpoll_interest_t*)event->data.ptr;
  698. assert(inst);
  699. #if 1 //DEBUG
  700. assert(inst->owner == ep);
  701. exist = evtpoll__find_interest(ep, inst->fd);
  702. assert(exist);
  703. assert(exist == inst);
  704. #endif
  705. if (event->events & EPOLLIN) { // read
  706. ret = evtpoll__deal_inner(inst, EV_INTEREST_ENTRY_IN_IDX, data, cancel);
  707. if (!ret && cancel) {
  708. evtpoll__unsubscribe_read(ep, exist);
  709. }
  710. event->events &= ~(EPOLLIN);
  711. return ret;
  712. }
  713. if (event->events & EPOLLOUT) { // write
  714. ret = evtpoll__deal_inner(inst, EV_INTEREST_ENTRY_OUT_IDX, data, cancel);
  715. if (!ret && cancel) {
  716. evtpoll__unsubscribe_write(ep, exist);
  717. }
  718. event->events &= ~(EPOLLOUT);
  719. return ret;
  720. }
  721. return -1;
  722. }
  723. int evtpoll_wait(evtpoll_t* ep, struct epoll_event event_array[], int event_array_size, int timeout)
  724. {
  725. int nfds;
  726. do
  727. {
  728. nfds = epoll_wait(ep->fd, event_array, event_array_size, timeout);
  729. } while (nfds == -1 && errno == EINTR);
  730. if (nfds == 0) {
  731. assert(timeout != -1);
  732. return 0;
  733. }
  734. if (nfds == -1) {
  735. WLog_ERR(TAG, "epoll wait error: %d", errno);
  736. return -1;
  737. }
  738. return nfds;
  739. }
  740. int evtpoll_loop(evtpoll_t* ep, int timeout)
  741. {
  742. int nfds;
  743. int ret = -1;
  744. return ret;
  745. }
  746. void evtpoll_destroy(evtpoll_t* evt_poll)
  747. {
  748. evtpoll__interest_clear(evt_poll);
  749. assert(evtpoll__interest_empty(evt_poll));
  750. close(evt_poll->fd);
  751. free(evt_poll);
  752. }
  753. #endif //NOT _WIN32