免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123
最近访问板块 发新帖
楼主: linux_c_py_php
打印 上一主题 下一主题

[C++] 【开源】C++异步网络框架,希望对感兴趣的同学带来一些启发。 [复制链接]

论坛徽章:
17
处女座
日期:2013-08-27 09:59:352015亚冠之柏太阳神
日期:2015-07-30 10:16:402015亚冠之萨济拖拉机
日期:2015-07-29 18:58:182015年亚洲杯之巴勒斯坦
日期:2015-03-06 17:38:17摩羯座
日期:2014-12-11 21:31:34戌狗
日期:2014-07-20 20:57:32子鼠
日期:2014-05-15 16:25:21亥猪
日期:2014-02-11 17:32:05丑牛
日期:2014-01-20 15:45:51丑牛
日期:2013-10-22 11:12:56双子座
日期:2013-10-18 16:28:17白羊座
日期:2013-10-18 10:50:45
21 [报告]
发表于 2013-10-25 16:18 |只看该作者
回复 20# cxytz01


    调试程序啊,通常来讲assert会明确的报告错误所在的代码信息(文件名,行号等)。通常用在不可能出错却出错的地方。

论坛徽章:
4
亥猪
日期:2013-09-27 13:50:29酉鸡
日期:2013-10-09 13:08:59丑牛
日期:2013-10-20 11:16:47亥猪
日期:2013-10-26 11:50:59
22 [报告]
发表于 2013-10-26 11:14 |只看该作者
1, sample_server.cc里面 实现 my_client要继承ez_handler, 而my_server : ez_listen_handler, 实在感觉有点突兀
2, 感觉ez_data 跟ez_connection 有共同的on_event,这里不是很明白可不可以直接存个ez_connection的指针算了给epoll_data结构体算了
胡乱说的,LZ明鉴

论坛徽章:
4
水瓶座
日期:2013-09-06 12:27:30摩羯座
日期:2013-09-28 14:07:46处女座
日期:2013-10-24 14:25:01酉鸡
日期:2014-04-07 11:54:15
23 [报告]
发表于 2013-10-26 20:29 |只看该作者
AssassinPig 发表于 2013-10-26 11:14
1, sample_server.cc里面 实现 my_client要继承ez_handler, 而my_server : ez_listen_handler, 实在感觉有 ...


嗯, 是的, ez_listen_handler可以统一到ez_handler里, 我设计ez_server的时候想过, 但没有落实, 我会考虑统一到ez_handler.

论坛徽章:
4
水瓶座
日期:2013-09-06 12:27:30摩羯座
日期:2013-09-28 14:07:46处女座
日期:2013-10-24 14:25:01酉鸡
日期:2014-04-07 11:54:15
24 [报告]
发表于 2013-10-26 20:35 |只看该作者
AssassinPig 发表于 2013-10-26 11:14
1, sample_server.cc里面 实现 my_client要继承ez_handler, 而my_server : ez_listen_handler, 实在感觉有 ...


对了,问题2没有回答你, 问题2我想是不可以的.

epoll_ctl修改事件的接口要求必须知道fd已经注册了什么事件, 所以我希望有一个地方可以记录这些信息, 所以这个信息记录在哪里是一个选择.

真正的意义是ez_poll的接口是int fd -> ez_fd *的关系, 而ez_fd是用户资源, 我不希望将属于框架内部的信息暴露在用户可触摸的ez_fd结构中, 尤其是涉及到"延迟删除"的部分的逻辑, 一个用户的资源ez_fd, 而我却依赖它的生命期来做框架内部逻辑的维持, 非常不合理.

如果你亲自去设计, 估计也遇到同样的思考, 做出类似的决定.

论坛徽章:
0
25 [报告]
发表于 2014-05-16 15:19 |只看该作者
怎么代码的连接失效了

论坛徽章:
4
水瓶座
日期:2013-09-06 12:27:30摩羯座
日期:2013-09-28 14:07:46处女座
日期:2013-10-24 14:25:01酉鸡
日期:2014-04-07 11:54:15
26 [报告]
发表于 2014-05-17 13:11 |只看该作者
自由若水 发表于 2014-05-16 15:19
怎么代码的连接失效了


可以看这个:https://code.csdn.net/qq120848369/simple_io/tree/master

论坛徽章:
2
申猴
日期:2014-04-17 14:37:17CU十四周年纪念徽章
日期:2018-06-23 16:03:03
27 [报告]
发表于 2014-05-19 10:22 |只看该作者
楼主404啊,想围观下代码

论坛徽章:
11
未羊
日期:2013-12-16 12:45:4615-16赛季CBA联赛之青岛
日期:2016-04-11 19:17:4715-16赛季CBA联赛之广夏
日期:2016-04-06 16:34:012015亚冠之卡尔希纳萨夫
日期:2015-11-10 10:04:522015亚冠之大阪钢巴
日期:2015-07-30 18:29:402015亚冠之城南
日期:2015-06-15 17:56:392015亚冠之卡尔希纳萨夫
日期:2015-05-15 15:19:272015亚冠之山东鲁能
日期:2015-05-14 12:38:13金牛座
日期:2014-12-04 15:34:06子鼠
日期:2014-10-16 13:40:4715-16赛季CBA联赛之八一
日期:2016-07-22 09:41:40
28 [报告]
发表于 2014-05-19 12:04 |只看该作者
我也发一个, 刚写完

  1. #include "list_head.h"
  2. #include "fdset.h"
  3. #include "fdset_in.h"
  4. #include "mem.h"
  5. #include "lock.h"
  6. #include "now.h"
  7. #include "mbuf.h"
  8. #include "utils.h"
  9. #include "fdctxpool.h"
  10. #include <unistd.h>
  11. #include <sys/socket.h>
  12. #include <sys/epoll.h>
  13. #include <sys/eventfd.h>
  14. #include <sys/timerfd.h>
  15. #include <string.h>

  16. #define epoll_mask(x) (x | EPOLLONESHOT | EPOLLET)
  17. #define stat_ready 0
  18. #define stat_busy 1

  19. typedef struct tag_fdset {
  20.     int fd, efd, tfd;
  21.     int threads;
  22.     int fdctx_lck, timer_lck;
  23.     struct list_head fdctx_head;
  24.     struct list_head timer_head;
  25. } fdset;

  26. typedef struct tag_timer_notify {
  27.     uint32_t id;
  28.     uint32_t tms;
  29.     fd_contex* fdctx;
  30.     struct list_head fdset_entry;
  31.     struct list_head fdctx_entry;
  32. } timer_notify;

  33. struct my_buffer* buffer_reserve(fd_contex* fdctx, uint32_t bytes)
  34. {
  35.     struct my_buffer* mbuf = NULL;
  36.     if (fdctx->read_mbuf != NULL) {
  37.         mbuf = fdctx->read_mbuf;
  38.         fdctx->read_mbuf = NULL;
  39.     } else {
  40.         mbuf = mbuf_alloc_2(bytes);
  41.     }
  42.     return mbuf;
  43. }

  44. static int io_read(fd_contex* fdctx)
  45. {
  46.     int n, error = 0;
  47.     struct fd_struct* fds = fdctx->fds;
  48.     struct my_buffer* mbuf = NULL;

  49.     if (fds->bytes > 0) {
  50. LABEL:
  51.         mbuf = buffer_reserve(fdctx, fds->bytes);
  52.         if (mbuf != NULL) {
  53.             if (fds->tcp0_udp1 == 0) {
  54.                 n = do_tcp_read(fds->fd, mbuf);
  55.                 if (n == -1) {
  56.                     error = errno;
  57.                 }
  58.             } else {
  59.                 n = do_udp_read(fds->fd, mbuf);
  60.                 if (n == -1) {
  61.                     error = EAGAIN;
  62.                 }
  63.             }
  64.         } else {
  65.             error = ENOMEM;
  66.         }
  67.     }

  68.     if (error != EWOULDBLOCK && error != EAGAIN) {
  69.         n = fds->read(fds, mbuf, error);
  70.         if (n > 0) {
  71.             fds->bytes = n;
  72.             goto LABEL;
  73.         }
  74.     } else {
  75.         fds->bytes = mbuf->length;
  76.         fdctx->read_mbuf = mbuf;
  77.         n = 0;
  78.     }
  79.     return n;
  80. }

  81. static int io_write(fd_contex* fdctx)
  82. {
  83.     int n;
  84.     struct sockaddr_in* in;
  85.     fdctx->fds->mask &= (~EPOLLOUT);
  86.     struct my_buffer* mbuf = NULL;

  87.     while (1) {
  88.         if (fdctx->write_mbuf != NULL) {
  89.             mbuf = fdctx->write_mbuf;
  90.             fdctx->write_mbuf = NULL;
  91.         } else {
  92.             mbuf = fdctx->fds->write(fdctx->fds, &in);
  93.         }

  94.         if (mbuf == NULL) {
  95.             break;
  96.         }

  97.         if (fdctx->fds->tcp0_udp1 == 0) {
  98.             n = do_tcp_write(fdctx->fds->fd, mbuf);
  99.         } else {
  100.             n = do_udp_write(fdctx->fds->fd, mbuf, in);
  101.         }

  102.         if (mbuf->length != 0) {
  103.             fdctx->write_mbuf = mbuf;
  104.             fdctx->fds->mask |= EPOLLOUT;
  105.             break;
  106.         }
  107.         mbuf->mop->free(mbuf);
  108.     }
  109.     return n;
  110. }

  111. static int io_proc(fd_contex* fdctx, uint32_t mask)
  112. {
  113.     int n = 0;
  114.     struct fd_struct* fds = fdctx->fds;

  115.     if (mask & (EPOLLERR | EPOLLHUP)) {
  116.         fds->read(fds, NULL, EBADF);
  117.         return -1;
  118.     }

  119.     if (mask & (EPOLLIN | EPOLLPRI)) {
  120.         n = io_read(fdctx);
  121.         if (n == -1) {
  122.             return -1;
  123.         }
  124.     }

  125.     if (mask & EPOLLRDHUP) {
  126.         n = fds->read(fds, NULL, ESHUTDOWN);
  127.         if (n == -1) {
  128.             return -1;
  129.         }
  130.     }

  131.     if (mask & EPOLLOUT) {
  132.         n = io_write(fdctx);
  133.     }

  134.     fdctx->ev.events = epoll_mask(fdctx->fds->mask);
  135.     if (n == -1) {
  136.         n = fds->read(fds, NULL, errno);
  137.     }
  138.     return n;
  139. }

  140. static void timer_expires(fdset* fset)
  141. {
  142.     fd_contex* fdctx;
  143.     uint32_t tms = now();
  144.     LIST_HEAD(head);
  145.     struct list_head* ent;

  146.     lock(&fset->timer_lck);
  147.     for (ent = fdctx->timer_head.next; ent != &fdctx->timer_head; ent = ent->next) {
  148.         timer_notify* notify = list_entry(ent, timer_notify, fdset_entry);
  149.         if (notify->tms > tms) {
  150.             break;
  151.         }

  152.         fdctx = notify->fdctx;
  153.         handle_clone(fdctx->self);

  154.         list_del_init(&notify->fdset_entry);
  155.         list_del(&notify->fdctx_entry);
  156.         list_add(&notify->fdctx_entry, &head);
  157.     }
  158.     unlock(&fset->timer_lck);

  159.     while (!list_empty(&head)) {
  160.         timer_notify* notify = list_entry(head.next, timer_notify, fdctx_entry);
  161.         list_del(head.next);

  162.         fdctx = notify->fdctx;
  163.         fdctx->fds->notify(fdctx->fds, notify->id);
  164.         handle_release(fdctx->self);
  165.         my_free(notify);
  166.     }
  167. }

  168. static void looper(void* any, int fd, int efd)
  169. {
  170.     struct epoll_event events;
  171.     my_handle* handle = (my_handle *) any;

  172.     while (1) {
  173.         int nr = epoll_wait(fd, &events, 1, -1);
  174.         fdset* fset = (fdset *) handle_get(handle);
  175.         if (__builtin_expect(fset == NULL, 0)) {
  176.             break;
  177.         }

  178.         if (__builtin_expect(nr == 1, 1)) {
  179.             fd_contex* fdctx = (fd_contex *) events.data.ptr;
  180.             if (__builtin_expect(fdctx != NULL, 1)) {
  181.                 lock(&fdctx->busy_lck);
  182.                 int stat = __sync_val_compare_and_swap(&fdctx->stat, stat_ready, stat_busy);
  183.                 unlock(&fdctx->busy_lck);

  184.                 if (stat == stat_ready) {
  185.                     handle_get(fdctx->self);
  186.                     while (fdctx->busy);
  187.                     fdctx->ev.events = 0;

  188.                     nr = io_proc(fdctx, events.events);
  189.                     if (nr != -1) {
  190.                         epoll_ctl(fd, EPOLL_CTL_MOD, fdctx->fds->fd, &fdctx->ev);
  191.                     }
  192.                     fdctx->stat = stat_ready;
  193.                     handle_put(fdctx->self);
  194.                 }
  195.             } else {
  196.                 timer_expires(fset);
  197.             }
  198.         } else if (nr != -1 || EINTR != errno) {
  199.             printf("what's up? n = %d, errno = %d\n", nr, errno);
  200.         }

  201.         handle_put(handle);
  202.     }

  203.     int n = handle_release(handle);
  204.     if (n == 0) {
  205.         epoll_ctl(fd, EPOLL_CTL_DEL, efd, NULL);
  206.         close(efd);
  207.         close(fd);
  208.     }
  209. }

  210. static void fset_delete(void* addr)
  211. {
  212.     fdset* fset = (fdset *) addr;
  213.     epoll_ctl(fset->fd, EPOLL_CTL_DEL, fset->tfd, NULL);
  214.     close(fset->tfd);

  215.     while (!list_empty(&fset->timer_head)) {
  216.         struct list_head* ent = fset->timer_head.next;
  217.         list_del_init(ent);
  218.     }

  219.     while (!list_empty(&fset->fdctx_head)) {
  220.         struct list_head* ent = fset->fdctx_head.next;
  221.         list_del(ent);
  222.         fd_contex* fdctx = list_entry(ent, fd_contex, set_entry);
  223.         epoll_ctl(fset->fd, EPOLL_CTL_DEL, fdctx->fds->fd, NULL);
  224.         handle_dettach(fdctx->self);
  225.     }

  226.     if (fset->threads != 0) {
  227.         uint64_t n = 1;
  228.         write(fset->efd, &n, sizeof(n));
  229.     } else {
  230.         epoll_ctl(fset->fd, EPOLL_CTL_DEL, fset->efd, NULL);
  231.         close(fset->efd);
  232.         close(fset->fd);
  233.     }
  234.     my_free(fset);
  235. }

  236. int fdset_join(void* set)
  237. {
  238.     my_handle* hset = (my_handle *) set;
  239.     fdset* fset = (fdset *) handle_get(hset);
  240.     if (fset == NULL) {
  241.         errno = -EBADF;
  242.         return -1;
  243.     }

  244.     int fd = fset->fd;
  245.     int efd = fset->efd;
  246.     __sync_add_and_fetch(&fset->threads, 1);

  247.     handle_clone(hset);
  248.     handle_put(hset);
  249.     looper(hset, fd, efd);
  250.     return 0;
  251. }

  252. void* fdset_new(uint32_t size)
  253. {
  254.     struct epoll_event event;
  255.     int tfd = timerfd_create(CLOCK_MONOTONIC, 0);
  256.     if (tfd == -1) {
  257.         return NULL;
  258.     }

  259.     struct itimerspec timerspec = {
  260.         .it_interval = {0, 0},
  261.         .it_value = {0, 0}
  262.     };
  263.     int n = timerfd_settime(tfd, 0, &timerspec, NULL);
  264.     if (n == -1) {
  265.         goto LABEL5;
  266.     }

  267.     int fd = epoll_create(size);
  268.     if (fd == -1) {
  269.         goto LABEL5;
  270.     }

  271.     event.events = epoll_mask(EPOLLIN);
  272.     event.data.ptr = NULL;
  273.     n = epoll_ctl(fd, EPOLL_CTL_ADD, tfd, &event);
  274.     if (n == -1) {
  275.         goto LABEL4;
  276.     }

  277.     int efd = eventfd(0, 0);
  278.     if (efd == -1) {
  279.         goto LABEL3;
  280.     }

  281.     event.data.fd = fd;
  282.     event.events = EPOLLIN;
  283.     n = epoll_ctl(fd, EPOLL_CTL_ADD, efd, &event);
  284.     if (n == -1) {
  285.         goto LABEL2;
  286.     }

  287.     errno = -ENOMEM;
  288.     fdset* fset = (fdset *) my_malloc(sizeof(fdset));
  289.     if (fset == NULL) {
  290.         goto LABEL1;
  291.     }

  292.     my_handle* handle = handle_attach(fset, fset_delete);
  293.     if (handle == NULL) {
  294.         goto LABEL0;
  295.     }

  296.     INIT_LIST_HEAD(&fset->fdctx_head);
  297.     INIT_LIST_HEAD(&fset->timer_head);
  298.     fset->fdctx_lck = 0;
  299.     fset->timer_lck = 0;
  300.     fset->fd = fd;
  301.     fset->efd = efd;
  302.     fset->threads = 0;
  303.     fset->tfd = tfd;
  304.     return (void *) handle;

  305. LABEL0:
  306.     my_free(fset);
  307. LABEL1:
  308.     epoll_ctl(fd, EPOLL_CTL_DEL, efd, NULL);
  309. LABEL2:
  310.     close(efd);
  311. LABEL3:
  312.     epoll_ctl(fd, EPOLL_CTL_DEL, tfd, NULL);
  313. LABEL4:
  314.     close(fd);
  315. LABEL5:
  316.     close(tfd);
  317.     return NULL;
  318. }

  319. static void unlink_from_fdset(fdset* fset, fd_contex* fdctx)
  320. {
  321.     lock(&fset->fdctx_lck);
  322.     list_del(&fdctx->set_entry);
  323.     unlock(&fset->fdctx_lck);

  324.     struct list_head* ent = fdctx->timer_head.next;
  325.     if (!list_empty(ent)) {
  326.         lock(&fset->timer_lck);
  327.         for (; ent != &fdctx->timer_head; ent = ent->next) {
  328.             timer_notify* notify = list_entry(ent, timer_notify, fdctx_entry);
  329.             list_del_init(&notify->fdset_entry);
  330.         }
  331.         unlock(&fset->timer_lck);
  332.     }

  333.     struct fd_struct* fds = fdctx->fds;
  334.     epoll_ctl(fset->fd, EPOLL_CTL_DEL, fds->fd, NULL);
  335. }

  336. static void fd_contex_free(void* addr)
  337. {
  338.     fd_contex* fdctx = (fd_contex *) addr;
  339.     while (1) {
  340.         int stat = __sync_val_compare_and_swap(&fdctx->stat, stat_ready, stat_busy);
  341.         if (stat == stat_ready) {
  342.             break;
  343.         }
  344.         sched_yield();
  345.     }

  346.     int need_notify = 1;
  347.     fdset* fset = (fdset *) handle_get(fdctx->hset);
  348.     if (fset != NULL) {
  349.         if (!list_empty(&fdctx->set_entry)) {
  350.             unlink_from_fdset(fset, fdctx);
  351.         } else {
  352.             need_notify = 0;
  353.         }
  354.         handle_release(fdctx->self);
  355.         handle_put(fdctx->hset);
  356.     }
  357.     handle_release(fdctx->hset);

  358.     while (!list_empty(&fdctx->timer_head)) {
  359.         struct list_head* ent = fdctx->timer_head.next;
  360.         list_del(ent);
  361.         timer_notify* notify = list_entry(ent, timer_notify, fdctx_entry);
  362.         my_free(notify);
  363.     }

  364.     if (need_notify == 1) {
  365.         struct fd_struct* fds = fdctx->fds;
  366.         fds->detach(fds);
  367.     }

  368.     if (fdctx->read_mbuf != NULL) {
  369.         fdctx->read_mbuf->mop->free(fdctx->read_mbuf);
  370.     }

  371.     if (fdctx->write_mbuf != NULL) {
  372.         fdctx->write_mbuf->mop->free(fdctx->write_mbuf);
  373.     }
  374.     fd_contex_put(fdctx);
  375. }

  376. my_handle* fdset_attach_fd(void* set, struct fd_struct* fds)
  377. {
  378.     if (fds->fd == -1) {
  379.         errno = -EINVAL;
  380.         return NULL;
  381.     }

  382.     if (-1 == make_none_block(fds->fd)) {
  383.         return NULL;
  384.     }

  385.     my_handle* hset = (my_handle *) set;
  386.     fdset* fset = (fdset *) handle_get(hset);
  387.     if (fset == NULL) {
  388.         errno = -EBADF;
  389.         return NULL;
  390.     }
  391.     errno = -ENOMEM;

  392.     fd_contex* fdctx = fd_contex_get();
  393.     if (fdctx == NULL) {
  394.         handle_put(hset);
  395.         return NULL;
  396.     }

  397.     my_handle* handle = handle_attach(fdctx, fd_contex_free);
  398.     if (handle == NULL) {
  399.         fd_contex_put(fdctx);
  400.         handle_put(hset);
  401.         return NULL;
  402.     }

  403.     handle_clone(handle);
  404.     fdctx->self = handle;
  405.     handle_clone(hset);
  406.     fdctx->hset = hset;

  407.     fdctx->fds = fds;
  408.     fdctx->read_mbuf = NULL;
  409.     fdctx->write_mbuf = NULL;
  410.     fdctx->busy = 0;
  411.     fdctx->busy_lck = 0;
  412.     INIT_LIST_HEAD(&fdctx->set_entry);
  413.     INIT_LIST_HEAD(&fdctx->timer_head);

  414.     fdctx->ev.events = epoll_mask(fds->mask);
  415.     fdctx->ev.data.ptr = fdctx;

  416.     int n = epoll_ctl(fset->fd, EPOLL_CTL_ADD, fds->fd, &fdctx->ev);
  417.     if (-1 == n) {
  418.         handle_release(handle);
  419.         handle_dettach(handle);
  420.         handle = NULL;
  421.     } else {
  422.         lock(&fset->fdctx_lck);
  423.         list_add(&fdctx->set_entry, &fset->fdctx_head);
  424.         unlock(&fset->fdctx_lck);
  425.         fdctx->stat = stat_ready;
  426.     }
  427.     handle_put(hset);
  428.     return handle;
  429. }

  430. void fdset_delete(void* hset)
  431. {
  432.     handle_dettach((my_handle *) hset);
  433. }

  434. int fdset_update_fdmask(my_handle* handle)
  435. {
  436.     errno = -EBADF;
  437.     fd_contex* fdctx = (fd_contex *) handle_get(handle);
  438.     if (fdctx == NULL) {
  439.         return -1;
  440.     }

  441.     fdset* fset = (fdset *) handle_get(fdctx->hset);
  442.     if (fset == NULL) {
  443.         handle_put(handle);
  444.         return -1;
  445.     }

  446.     struct fd_struct* fds = fdctx->fds;
  447.     lock(&fdctx->busy_lck);
  448.     fdctx->busy = 1;
  449.     unlock(&fdctx->busy_lck);

  450.     uint32_t old_mask = fdctx->ev.events;
  451.     uint32_t new_mask = epoll_mask(fds->mask);

  452.     if (old_mask == new_mask || fdctx->stat == stat_busy) {
  453.         fdctx->busy = 0;
  454.         handle_put(fdctx->hset);
  455.         handle_put(handle);
  456.         return 0;
  457.     }

  458.     fdctx->ev.events = new_mask;
  459.     int n = epoll_ctl(fset->fd, EPOLL_CTL_MOD, fds->fd, &fdctx->ev);
  460.     if (n == -1) {
  461.         fdctx->ev.events = old_mask;
  462.     }
  463.     fdctx->busy = 0;

  464.     handle_put(fdctx->hset);
  465.     handle_put(handle);
  466.     return n;
  467. }

  468. static int fdset_add_timer(fdset* fset, timer_notify* notify, uint32_t ms)
  469. {
  470.     struct list_head* ent;
  471.     lock(&fset->timer_lck);
  472.     for (ent = fset->timer_head.prev; ent != &fset->timer_head; ent = ent->prev) {
  473.         timer_notify* cur = list_entry(ent, timer_notify, fdset_entry);
  474.         if (cur->tms <= notify->tms) {
  475.             break;
  476.         }
  477.     }

  478.     int n = 0;
  479.     if (ent == &fset->timer_head) {
  480.         struct itimerspec timerspec;

  481.         timerspec.it_value.tv_sec = ms / 1000;
  482.         timerspec.it_value.tv_nsec = (ms - timerspec.it_value.tv_sec * 1000) * 1000000;
  483.         timerspec.it_interval.tv_sec = 0;
  484.         timerspec.it_interval.tv_nsec = 0;
  485.         n = timerfd_settime(fset->tfd, 0, &timerspec, NULL);
  486.     }

  487.     if (n == 0) {
  488.         list_add(&notify->fdset_entry, ent);
  489.     }
  490.     unlock(&fset->timer_lck);
  491.     return n;
  492. }

  493. int fdset_sched(my_handle* handle, uint32_t ms, uint32_t id)
  494. {
  495.     fd_contex* fdctx = (fd_contex *) handle_get(handle);
  496.     if (fdctx == NULL) {
  497.         errno = -EBADF;
  498.         return -1;
  499.     }
  500.     fdset* fset = (fdset *) handle_get(fdctx->hset);
  501.     assert(fset != NULL);

  502.     int n = -1;
  503.     errno = -ENOMEM;
  504.     timer_notify* notify = (timer_notify *) my_malloc(sizeof(timer_notify));
  505.     if (notify != NULL) {
  506.         notify->id = id;
  507.         notify->tms = now() + ms;
  508.         notify->fdctx = fdctx;
  509.         list_add(&notify->fdctx_entry, &fdctx->timer_head);
  510.         n = fdset_add_timer(fset, notify, ms);
  511.         if (n == -1) {
  512.             my_free(notify);
  513.         } else {
  514.             handle_clone(handle);
  515.         }
  516.     }

  517.     handle_put(fdctx->hset);
  518.     handle_put(handle);
  519.     return n;
  520. }

  521. struct fd_struct* fd_struct_from(void* any)
  522. {
  523.     if (any == NULL) {
  524.         return NULL;
  525.     }

  526.     fd_contex* fdctx = (fd_contex *) any;
  527.     struct fd_struct* fds = fdctx->fds;
  528.     return fds;
  529. }
复制代码
linux_c_py_php 发表于 2014-05-17 13:11
可以看这个:https://code.csdn.net/qq120848369/simple_io/tree/master

论坛徽章:
0
29 [报告]
发表于 2015-10-08 15:44 |只看该作者
想看看,学习学习

论坛徽章:
15
射手座
日期:2014-11-29 19:22:4915-16赛季CBA联赛之青岛
日期:2017-11-17 13:20:09黑曼巴
日期:2017-07-13 19:13:4715-16赛季CBA联赛之四川
日期:2017-02-07 21:08:572015年亚冠纪念徽章
日期:2015-11-06 12:31:58每日论坛发贴之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-08-04 06:20:00程序设计版块每日发帖之星
日期:2015-07-12 22:20:002015亚冠之浦和红钻
日期:2015-07-08 10:10:132015亚冠之大阪钢巴
日期:2015-06-29 11:21:122015亚冠之广州恒大
日期:2015-05-22 21:55:412015年亚洲杯之伊朗
日期:2015-04-10 16:28:25
30 [报告]
发表于 2015-10-10 14:07 |只看该作者
本帖最后由 yulihua49 于 2015-10-10 14:12 编辑
linux_c_py_php 发表于 2013-10-23 16:37
发布一个源创的linux C++异步网络框架, 基于工作需求,偏重工程实践。

开发者不需关心 连接,监听,以及 ...


发现epoll有惊群,即使使用了EPOLLONESHOT。
很偶然,今天又被扑捉到一次。程序新增的防惊群代码:

  1.             fds = epoll_wait(g_epoll_fd, &event, 1 , -1);
  2.             if(fds < 0){
  3.                     ShowLog(1,"%s:epoll_wait err=%d,%s",__FUNCTION__,errno,strerror(errno));
  4.                 usleep(30000000);
  5.                 continue;
  6.                 }
  7.             task = (TCB *)event.data.ptr;
  8.             if(task->events) {//在加入epoll前清0
  9.                 ShowLog(1,"%s:task->events=%08X,conflict!",__FUNCTION__,task->events);//发现惊群
  10.                 continue;//丢掉它
  11.             }
  12.             task->events=event.events;
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP