日本搞逼视频_黄色一级片免费在线观看_色99久久_性明星video另类hd_欧美77_综合在线视频

國內(nèi)最全I(xiàn)T社區(qū)平臺 聯(lián)系我們 | 收藏本站
阿里云優(yōu)惠2
您當(dāng)前位置:首頁 > php框架 > 框架設(shè)計 > [libevent源碼分析] event_add

[libevent源碼分析] event_add

來源:程序員人生   發(fā)布時間:2015-03-23 07:53:54 閱讀次數(shù):3285次

event_add 把event往當(dāng)前event中的ev_base追加,如果需要定時,那末tv不能為空

int event_add(struct event *ev, const struct timeval *tv) { struct event_base *base = ev->ev_base; //event_add 會把event加入到他的ev_base成員里 const struct eventop *evsel = base->evsel; //對應(yīng)linux的epoll相干函數(shù) void *evbase = base->evbase; //對應(yīng)linux為 struct epollop /* * struct epollop * { * struct evepoll *fds; //分配nfiles個evepoll對象 * int nfds; //支持的最大軟限制數(shù)的句柄(上面的數(shù)組個數(shù)) * struct epoll_event* events; //分配nfiles(軟限制數(shù)) epoll_event對象 * int nevents; //nevents保存著上面events個數(shù) * int epfd; //保存著epoll_create的句柄 * } */ int res = 0; event_debug(( "event_add: event: %p, %s%s%scall %p", ev, ev->ev_events & EV_READ ? "EV_READ " : " ", ev->ev_events & EV_WRITE ? "EV_WRITE " : " ", tv ? "EV_TIMEOUT " : " ", ev->ev_callback)); assert(!(ev->ev_flags & ~EVLIST_ALL)); if (tv != NULL && !(ev->ev_flags & EVLIST_TIMEOUT)) { if (min_heap_reserve(&base->timeheap, 1 + min_heap_size(&base->timeheap)) == ⑴) return (⑴); /* ENOMEM == errno */ } if ((ev->ev_events & (EV_READ|EV_WRITE|EV_SIGNAL)) && !(ev->ev_flags & (EVLIST_INSERTED|EVLIST_ACTIVE))) { res = evsel->add(evbase, ev); //注冊or修改事件到epoll中去 if (res != ⑴) event_queue_insert(base, ev, EVLIST_INSERTED); //把ev插入到eventqeue中去 } /* * 如果說插入事件成功同時設(shè)置了超時時間 */ if (res != ⑴ && tv != NULL) { struct timeval now; /* *如果已存在了超時時間,那末就刪除這個超時節(jié)點 */ if (ev->ev_flags & EVLIST_TIMEOUT) event_queue_remove(base, ev, EVLIST_TIMEOUT); /* Check if it is active due to a timeout. Rescheduling * this timeout before the callback can be executed * removes it from the active list. */ if ((ev->ev_flags & EVLIST_ACTIVE) && (ev->ev_res & EV_TIMEOUT)) { /* See if we are just active executing this * event in a loop */ if (ev->ev_ncalls && ev->ev_pncalls) { /* Abort loop */ *ev->ev_pncalls = 0; } event_queue_remove(base, ev, EVLIST_ACTIVE); } gettime(base, &now); evutil_timeradd(&now, tv, &ev->ev_timeout); event_debug(( "event_add: timeout in %ld seconds, call %p", tv->tv_sec, ev->ev_callback)); event_queue_insert(base, ev, EVLIST_TIMEOUT);//加入到最小超時堆中去 } return (res); }
如果新加的事件不為空,當(dāng)前事件不是timeout時間,就為他在時間最小堆上分配1塊可用空間(如果最小堆有空間,就不會重新分配)
關(guān)于最小堆可以連接我的githup,libevent用最小堆來管理定時事件,根節(jié)點永久是最小的而且算法時間最小



如果事件是EV_READ、EV_WRITE、EV_SIGNAL,并且事件不是插入or激活狀態(tài),那末就加入事件
以epoll為例

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; /* * 信號的原理 * 1 設(shè)置信號處理函數(shù),保存原來的信號處理函數(shù)到event的ev_base->sh_old中去 * 2 如果是首次添加信號,那末需要為所有信號追加1個信號事件來源自event->ev_base->ev_signal * 同時設(shè)置event->ev_base->ev_signal->ev_signal_added,表示信號回調(diào)事件已設(shè)置了 * 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 */ //如果說當(dāng)前的epoll中已滿足不了新加入的句柄 if (epoll_recalc(ev->ev_base, epollop, fd) == ⑴) return (⑴); } 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; } //新加入事件設(shè)置的是可讀事件 if (ev->ev_events & EV_READ) events |= EPOLLIN; //新加入事件設(shè)置的是可寫事件 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) == ⑴) return (⑴); /* Update events responsible */ if (ev->ev_events & EV_READ) evep->evread = ev; if (ev->ev_events & EV_WRITE) evep->evwrite = ev; return (0); }

信號追加,libevent對信號采取sockpair 創(chuàng)建兩個互連socket,信號激起寫可寫sock,可讀加入到事件循環(huán)中去
根據(jù)信號ev_base->sig.evsigcaught[signumber]來判斷該信號是不是產(chǎn)生,下面是信號追加函數(shù)

int evsignal_add(struct event *ev) { int evsignal; struct event_base *base = ev->ev_base; //信號event的base struct evsignal_info *sig = &ev->ev_base->sig; //信號在ev_base的管理結(jié)構(gòu) if (ev->ev_events & (EV_READ|EV_WRITE)) //信號事件不支持可讀可寫事件 event_errx(1, "%s: EV_SIGNAL incompatible use", __func__); evsignal = EVENT_SIGNAL(ev); //信號的fd就是信號number assert(evsignal >= 0 && evsignal < NSIG); //信號不能超過NSIG這個數(shù) if (TAILQ_EMPTY(&sig->evsigevents[evsignal])) { //如果說該信號鏈表為空 event_debug(("%s: %p: changing signal handler", __func__, ev)); //設(shè)置信號處理函數(shù),同時,保存原來的信號處理函數(shù)到ev_base->sh_old中去 if (_evsignal_set_handler( base, evsignal, evsignal_handler) == ⑴) return (⑴); /* catch signals if they happen quickly */ evsignal_base = base; if (!sig->ev_signal_added) { if (event_add(&sig->ev_signal, NULL)) return (⑴); sig->ev_signal_added = 1; //加入epoll_wait中去 } } //把ev->ev_signal_next加入到sig->evsigevents[evsignal]的鏈表末端 /* multiple events may listen to the same signal */ TAILQ_INSERT_TAIL(&sig->evsigevents[evsignal], ev, ev_signal_next); return (0); }

信號回調(diào)函數(shù)

/* * 所有的信號都通用1個信號處理函數(shù) */ static void evsignal_handler(int sig) { int save_errno = errno; //保存毛病碼 if (evsignal_base == NULL) { event_warn( "%s: received signal %d, but have no base configured", __func__, sig); return; } evsignal_base->sig.evsigcaught[sig]++; //引發(fā)的信號number++ evsignal_base->sig.evsignal_caught = 1; //設(shè)置信號標(biāo)志,表示信號已觸發(fā) #ifndef HAVE_SIGACTION signal(sig, evsignal_handler); #endif /* Wake up our notification mechanism */ send(evsignal_base->sig.ev_signal_pair[0], "a", 1, 0); //通過寫sockpair寫數(shù)據(jù)來觸發(fā)epoll_wait返回 errno = save_errno; }

定時事件采取最小堆,定時值+當(dāng)前事件最為左后超時時間,加入到最小堆中去,主要在event_base_dispatch中使用

libeven 全部源碼分析和sample都在我的 githup

生活不易,碼農(nóng)辛苦
如果您覺得本網(wǎng)站對您的學(xué)習(xí)有所幫助,可以手機(jī)掃描二維碼進(jìn)行捐贈
程序員人生
------分隔線----------------------------
分享到:
------分隔線----------------------------
關(guān)閉
程序員人生
主站蜘蛛池模板: 久久精品视频偷拍 | 九九精品在线观看 | 一区二区三区欧美日韩 | 久久久福利 | 99视频观看 | 日韩精彩视频 | 天天av天天好逼 | 国产在线不卡一区 | 性做久久久久久免费观看欧美 | 日韩av在线免费看 | 欧美视频一区二区三区 | 国产激情在线 | 国产成人精品免高潮在线观看 | 日韩av一区在线 | 国产视频福利 | 精品国产传媒 | 国产一区二区精品 | 中文字幕日韩视频 | 国产精品视频999 | 国产精品免费观看 | 亚洲国产精品一区二区尤物区 | 国产精品久久久久久久久久久不卡 | 国产在线观看一区二区 | 国内激情 | 成人福利网 | 国内 美女 主播 精品 视频 | 久久久人 | 久久国产精品电影 | 国产一区二区三区高清 | 婷婷不卡| 国产精品久久久久一区二区三区 | 欧美成人性生活视频 | 中文字幕不卡一区 | 国产精品91一区二区三区 | 91在线播放视频 | 国产成人精品久久二区二区91 | 国产精品区在线观看 | 国产精品国产三级国产aⅴ原创 | 99re在线视频免费观看 | 在线免费激情视频 | 久久不卡 |