static int epoll_add(void *arg, struct event *ev) { struct epollop *epollop = arg; struct epoll_event epev = {0, {0}}; struct evepoll *evep; int fd, op, events; /* * x信号的原理 * 1 设置信号处理函数,保存原来的信号处理函数到event的ev_base->sh_old中去 * 2 如果是首次添加信号,那么需要为所有信号追加一个信号事件来源自event->ev_base->ev_signal * 同时设置event->ev_base->ev_signal->ev_signal_added,表示信号回调事件已经设置了 * 3 同时把事件追加到event->ev_base->ev_signal->evsigevents[signno]链表中去 */ if (ev->ev_events & EV_SIGNAL) //如果是加入的信号 return (evsignal_add(ev)); fd = ev->ev_fd; if (fd >= epollop->nfds) { /* Extent the file descriptor array as necessary */ //如果说当前的epoll中已经满足不了新加入的句柄 if (epoll_recalc(ev->ev_base, epollop, fd) == -1) return (-1); } evep = &epollop->fds[fd]; op = EPOLL_CTL_ADD; events = 0; //如果事件之前是可读 if (evep->evread != NULL) { events |= EPOLLIN; op = EPOLL_CTL_MOD; } //如果事件之前是可写 if (evep->evwrite != NULL) { events |= EPOLLOUT; op = EPOLL_CTL_MOD; } //新加入事件设置的是可读事件 if (ev->ev_events & EV_READ) events |= EPOLLIN; //新加入事件设置的是可写事件 if (ev->ev_events & EV_WRITE) events |= EPOLLOUT; epev.data.ptr = evep; epev.events = events; if (epoll_ctl(epollop->epfd, op, ev->ev_fd, &epev) == -1) return (-1); /* Update events responsible */ if (ev->ev_events & EV_READ) evep->evread = ev; if (ev->ev_events & EV_WRITE) evep->evwrite = ev; return (0); }
static int epoll_add(void *arg, struct event *ev) { struct epollop *epollop = arg; struct epoll_event epev = {0, {0}}; struct evepoll *evep; int fd, op, events; //signal 的添加部分,直接调用signal添加函数 if (ev->ev_events & EV_SIGNAL) return (evsignal_add(ev)); fd = ev->ev_fd; //fd总是系统中空闲的最小fd,判断fds是否够,不够扩大 if (fd >= epollop->nfds) { /* Extent the file descriptor array as necessary */ if (epoll_recalc(ev->ev_base, epollop, fd) == -1) return (-1); } //fds 和 events数组的索引是一致的都是fd evep = &epollop->fds[fd]; op = EPOLL_CTL_ADD; events = 0; //若相应的fd已经添加了相应的event //再次添加回覆盖evepoll中的event指针 if (evep->evread != NULL) { events |= EPOLLIN; op = EPOLL_CTL_MOD; } if (evep->evwrite != NULL) { events |= EPOLLOUT; op = EPOLL_CTL_MOD; } if (ev->ev_events & EV_READ) events |= EPOLLIN; if (ev->ev_events & EV_WRITE) events |= EPOLLOUT; epev.data.fd = fd; epev.events = events; if (epoll_ctl(epollop->epfd, op, ev->ev_fd, &epev) == -1) return (-1); /* Update events responsible */ if (ev->ev_events & EV_READ) evep->evread = ev; if (ev->ev_events & EV_WRITE) evep->evwrite = ev; return (0); }
static int epoll_add(void *arg, struct event *ev) { struct epollop *epollop = arg; struct epoll_event epev = {0, {0}}; struct evepoll *evep; int fd, op, events; if (ev->ev_events & EV_SIGNAL) return (evsignal_add(ev)); fd = ev->ev_fd; if (fd >= epollop->nfds) { /* Extent the file descriptor array as necessary */ if (epoll_recalc(ev->ev_base, epollop, fd) == -1) return (-1); } evep = &epollop->fds[fd]; op = EPOLL_CTL_ADD; events = 0; if (evep->evread != NULL) { events |= EPOLLIN; op = EPOLL_CTL_MOD; } if (evep->evwrite != NULL) { events |= EPOLLOUT; op = EPOLL_CTL_MOD; } if (ev->ev_events & EV_READ) events |= EPOLLIN; if (ev->ev_events & EV_WRITE) events |= EPOLLOUT; epev.data.ptr = evep; epev.events = events; if (epoll_ctl(epollop->epfd, op, ev->ev_fd, &epev) == -1) return (-1); /* Update events responsible */ if (ev->ev_events & EV_READ) evep->evread = ev; if (ev->ev_events & EV_WRITE) evep->evwrite = ev; return (0); }
static int epoll_add(void *arg, struct event *ev) { struct epollop *epollop = arg; struct epoll_event epev = {0, {0}}; struct evepoll *evep; int fd, op, events; if (ev->ev_events & EV_SIGNAL) return (evsignal_add(ev)); fd = ev->ev_fd; if (fd >= epollop->nfds) { if (epoll_recalc(ev->ev_base, epollop, fd) == -1) return (-1); } evep = &epollop->fds[fd]; op = EPOLL_CTL_ADD; events = 0; if (evep->evread != NULL) { events |= EPOLLIN; op = EPOLL_CTL_MOD; } if (evep->evwrite != NULL) { events |= EPOLLOUT; op = EPOLL_CTL_MOD; } if (ev->ev_events & EV_READ) events |= EPOLLIN; if (ev->ev_events & EV_WRITE) events |= EPOLLOUT; epev.data.fd = fd; epev.events = events; if (epoll_ctl(epollop->epfd, op, ev->ev_fd, &epev) == -1) return (-1); if (ev->ev_events & EV_READ) evep->evread = ev; if (ev->ev_events & EV_WRITE) evep->evwrite = ev; return (0); }
int epoll_add(void *arg, struct event *ev) { struct epollop *epollop = arg; struct epoll_event epev; struct evepoll *evep; int fd, op, events; if (ev->ev_events & EV_SIGNAL) return (evsignal_add(&epollop->evsigmask, ev)); fd = ev->ev_fd; if (fd >= epollop->nfds) { /* Extent the file descriptor array as necessary */ if (epoll_recalc(epollop, fd) == -1) return (-1); } evep = &epollop->fds[fd]; // NOTE: 以fd作为下标 的一个指针,指向数组, op = EPOLL_CTL_ADD; events = 0; if (evep->evread != NULL) { events |= EPOLLIN; op = EPOLL_CTL_MOD; } if (evep->evwrite != NULL) { events |= EPOLLOUT; op = EPOLL_CTL_MOD; } if (ev->ev_events & EV_READ) events |= EPOLLIN; if (ev->ev_events & EV_WRITE) events |= EPOLLOUT; epev.data.ptr = evep; // NOTE: 这里作为一个指针 epev.events = events; // NOTE 疑问, epev是局部变量,可以直接传指针? 应该是没问题,内核复制一份 if (epoll_ctl(epollop->epfd, op, ev->ev_fd, &epev) == -1) return (-1); /* Update events responsible */ if (ev->ev_events & EV_READ) evep->evread = ev; // 在这里真正复制了 对应的事件 返回的时候就能看到 if (ev->ev_events & EV_WRITE) evep->evwrite = ev; return (0); }