mirror of https://github.com/F-Stack/f-stack.git
562 lines
13 KiB
C++
562 lines
13 KiB
C++
|
|
|||
|
/**
|
|||
|
* Tencent is pleased to support the open source community by making MSEC available.
|
|||
|
*
|
|||
|
* Copyright (C) 2016 THL A29 Limited, a Tencent company. All rights reserved.
|
|||
|
*
|
|||
|
* Licensed under the GNU General Public License, Version 2.0 (the "License");
|
|||
|
* you may not use this file except in compliance with the License. You may
|
|||
|
* obtain a copy of the License at
|
|||
|
*
|
|||
|
* https://opensource.org/licenses/GPL-2.0
|
|||
|
*
|
|||
|
* Unless required by applicable law or agreed to in writing, software distributed under the
|
|||
|
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
|||
|
* either express or implied. See the License for the specific language governing permissions
|
|||
|
* and limitations under the License.
|
|||
|
*/
|
|||
|
|
|||
|
|
|||
|
/**
|
|||
|
* @filename epoll_proxy.cpp
|
|||
|
* @info epoll for micro thread manage
|
|||
|
*/
|
|||
|
|
|||
|
#include "epoll_proxy.h"
|
|||
|
#include "micro_thread.h"
|
|||
|
|
|||
|
using namespace NS_MICRO_THREAD;
|
|||
|
|
|||
|
/**
|
|||
|
* @brief <EFBFBD><EFBFBD><EFBFBD>캯<EFBFBD><EFBFBD>
|
|||
|
*/
|
|||
|
EpollProxy::EpollProxy()
|
|||
|
{
|
|||
|
_maxfd = EpollProxy::DEFAULT_MAX_FD_NUM;
|
|||
|
_epfd = -1;
|
|||
|
_evtlist = NULL;
|
|||
|
_eprefs = NULL;
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* @brief epoll<EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD>, <EFBFBD><EFBFBD><EFBFBD>붯̬<EFBFBD>ڴ<EFBFBD><EFBFBD><EFBFBD>
|
|||
|
*/
|
|||
|
int EpollProxy::InitEpoll(int max_num)
|
|||
|
{
|
|||
|
int rc = 0;
|
|||
|
if (max_num > _maxfd) // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>õ<EFBFBD><C3B5><EFBFBD>Ŀ<EFBFBD>ϴ<EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>fd<66><64>Ŀ
|
|||
|
{
|
|||
|
_maxfd = max_num;
|
|||
|
}
|
|||
|
|
|||
|
_epfd = epoll_create(_maxfd);
|
|||
|
if (_epfd < 0)
|
|||
|
{
|
|||
|
rc = -1;
|
|||
|
goto EXIT_LABEL;
|
|||
|
}
|
|||
|
fcntl(_epfd, F_SETFD, FD_CLOEXEC);
|
|||
|
|
|||
|
_eprefs = new FdRef[_maxfd];
|
|||
|
if (NULL == _eprefs)
|
|||
|
{
|
|||
|
rc = -2;
|
|||
|
goto EXIT_LABEL;
|
|||
|
}
|
|||
|
|
|||
|
_evtlist = (EpEvent*)calloc(_maxfd, sizeof(EpEvent));
|
|||
|
if (NULL == _evtlist)
|
|||
|
{
|
|||
|
rc = -3;
|
|||
|
goto EXIT_LABEL;
|
|||
|
}
|
|||
|
|
|||
|
struct rlimit rlim;
|
|||
|
memset(&rlim, 0, sizeof(rlim));
|
|||
|
if (getrlimit(RLIMIT_NOFILE, &rlim) == 0)
|
|||
|
{
|
|||
|
if ((int)rlim.rlim_max < _maxfd)
|
|||
|
{
|
|||
|
rlim.rlim_cur = rlim.rlim_max;
|
|||
|
setrlimit(RLIMIT_NOFILE, &rlim);
|
|||
|
rlim.rlim_cur = _maxfd;
|
|||
|
rlim.rlim_max = _maxfd;
|
|||
|
setrlimit(RLIMIT_NOFILE, &rlim);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
EXIT_LABEL:
|
|||
|
|
|||
|
if (rc < 0)
|
|||
|
{
|
|||
|
TermEpoll();
|
|||
|
}
|
|||
|
|
|||
|
return rc;
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* @brief epoll<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD>
|
|||
|
*/
|
|||
|
void EpollProxy::TermEpoll()
|
|||
|
{
|
|||
|
if (_epfd > 0)
|
|||
|
{
|
|||
|
close(_epfd);
|
|||
|
_epfd = -1;
|
|||
|
}
|
|||
|
|
|||
|
if (_evtlist != NULL)
|
|||
|
{
|
|||
|
free(_evtlist);
|
|||
|
_evtlist = NULL;
|
|||
|
}
|
|||
|
|
|||
|
if (_eprefs != NULL)
|
|||
|
{
|
|||
|
delete []_eprefs;
|
|||
|
_eprefs = NULL;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* @brief <EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>socket<EFBFBD><EFBFBD><EFBFBD><EFBFBD>epoll<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
* @param fdset <EFBFBD>߳<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>socket<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
* @return true <EFBFBD>ɹ<EFBFBD>, false ʧ<EFBFBD><EFBFBD>, ʧ<EFBFBD>ܻᾡ<EFBFBD><EFBFBD><EFBFBD>ع<EFBFBD>, <EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӱ<EFBFBD><EFBFBD>
|
|||
|
*/
|
|||
|
bool EpollProxy::EpollAdd(EpObjList& obj_list)
|
|||
|
{
|
|||
|
bool ret = true;
|
|||
|
EpollerObj *epobj = NULL;
|
|||
|
EpollerObj *epobj_error = NULL;
|
|||
|
TAILQ_FOREACH(epobj, &obj_list, _entry)
|
|||
|
{
|
|||
|
if (!EpollAddObj(epobj))
|
|||
|
{
|
|||
|
MTLOG_ERROR("epobj add failed, fd: %d", epobj->GetOsfd());
|
|||
|
epoll_assert(0);
|
|||
|
epobj_error = epobj;
|
|||
|
ret = false;
|
|||
|
goto EXIT_LABEL;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
EXIT_LABEL:
|
|||
|
|
|||
|
if (!ret)
|
|||
|
{
|
|||
|
TAILQ_FOREACH(epobj, &obj_list, _entry)
|
|||
|
{
|
|||
|
if (epobj == epobj_error)
|
|||
|
{
|
|||
|
break;
|
|||
|
}
|
|||
|
EpollDelObj(epobj);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return ret;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/**
|
|||
|
* @brief <EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>socket<EFBFBD>Ƴ<EFBFBD>epoll<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
* @param fdset <EFBFBD>߳<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>socket<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
* @return true <EFBFBD>ɹ<EFBFBD>, false ʧ<EFBFBD><EFBFBD>
|
|||
|
*/
|
|||
|
bool EpollProxy::EpollDel(EpObjList& obj_list)
|
|||
|
{
|
|||
|
bool ret = true;
|
|||
|
|
|||
|
EpollerObj *epobj = NULL;
|
|||
|
TAILQ_FOREACH(epobj, &obj_list, _entry)
|
|||
|
{
|
|||
|
if (!EpollDelObj(epobj)) // failed also need continue, be sure ref count ok
|
|||
|
{
|
|||
|
MTLOG_ERROR("epobj del failed, fd: %d", epobj->GetOsfd());
|
|||
|
epoll_assert(0);
|
|||
|
ret = false;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return ret;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/**
|
|||
|
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD>epfd<EFBFBD><EFBFBD><EFBFBD><EFBFBD>epctrl, <EFBFBD>ɹ<EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD><EFBFBD>µ<EFBFBD>ǰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD>ֵ
|
|||
|
*/
|
|||
|
bool EpollProxy::EpollCtrlAdd(int fd, int events)
|
|||
|
{
|
|||
|
FdRef* item = FdRefGet(fd);
|
|||
|
if (NULL == item)
|
|||
|
{
|
|||
|
MT_ATTR_API(320851, 1); // fd error
|
|||
|
MTLOG_ERROR("epfd ref not find, failed, fd: %d", fd);
|
|||
|
epoll_assert(0);
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ü<EFBFBD><C3BC><EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̻<EFBFBD><CCBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ü<EFBFBD><C3BC><EFBFBD>, ʧ<><CAA7>Ҫ<EFBFBD>ع<EFBFBD>
|
|||
|
item->AttachEvents(events);
|
|||
|
|
|||
|
int old_events = item->GetListenEvents();
|
|||
|
int new_events = old_events | events;
|
|||
|
if (old_events == new_events) {
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
int op = old_events ? EPOLL_CTL_MOD : EPOLL_CTL_ADD;
|
|||
|
EpEvent ev;
|
|||
|
ev.events = new_events;
|
|||
|
ev.data.fd = fd;
|
|||
|
if ((epoll_ctl(_epfd, op, fd, &ev) < 0) && !(op == EPOLL_CTL_ADD && errno == EEXIST))
|
|||
|
{
|
|||
|
MT_ATTR_API(320850, 1); // epoll error
|
|||
|
MTLOG_ERROR("epoll ctrl failed, fd: %d, op: %d, errno: %d", fd, op, errno);
|
|||
|
item->DetachEvents(events);
|
|||
|
epoll_assert(0);
|
|||
|
return false;
|
|||
|
}
|
|||
|
item->SetListenEvents(new_events);
|
|||
|
|
|||
|
return true;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD>epfd<EFBFBD><EFBFBD><EFBFBD><EFBFBD>epctrl, <EFBFBD>ɹ<EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD><EFBFBD>µ<EFBFBD>ǰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD>ֵ
|
|||
|
*/
|
|||
|
bool EpollProxy::EpollCtrlDel(int fd, int events)
|
|||
|
{
|
|||
|
return EpollCtrlDelRef(fd, events, false);
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD>epfd<EFBFBD><EFBFBD><EFBFBD><EFBFBD>epctrl, <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ü<EFBFBD><EFBFBD><EFBFBD>, <EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ԥ<EFBFBD>賤<EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ÿ<EFBFBD>ζ<EFBFBD>epollctl
|
|||
|
*/
|
|||
|
bool EpollProxy::EpollCtrlDelRef(int fd, int events, bool use_ref)
|
|||
|
{
|
|||
|
FdRef* item = FdRefGet(fd);
|
|||
|
if (NULL == item)
|
|||
|
{
|
|||
|
MT_ATTR_API(320851, 1); // fd error
|
|||
|
MTLOG_ERROR("epfd ref not find, failed, fd: %d", fd);
|
|||
|
epoll_assert(0);
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
item->DetachEvents(events); // delete ʧ<>ܲ<EFBFBD><DCB2>ع<EFBFBD><D8B9><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
int old_events = item->GetListenEvents();
|
|||
|
int new_events = old_events &~ events; // Ĭ<><C4AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
|||
|
// <20><><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɾ<EFBFBD><C9BE>, <20><>Ҫ<EFBFBD>˲<EFBFBD><CBB2>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD>ɾ<EFBFBD><C9BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
if (use_ref)
|
|||
|
{
|
|||
|
new_events = old_events;
|
|||
|
if (0 == item->ReadRefCnt()) {
|
|||
|
new_events = new_events & ~EPOLLIN;
|
|||
|
}
|
|||
|
if (0 == item->WriteRefCnt()) {
|
|||
|
new_events = new_events & ~EPOLLOUT;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
if (old_events == new_events)
|
|||
|
{
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
int op = new_events ? EPOLL_CTL_MOD : EPOLL_CTL_DEL;
|
|||
|
EpEvent ev;
|
|||
|
ev.events = new_events;
|
|||
|
ev.data.fd = fd;
|
|||
|
if ((epoll_ctl(_epfd, op, fd, &ev) < 0) && !(op == EPOLL_CTL_DEL && errno == ENOENT))
|
|||
|
{
|
|||
|
MT_ATTR_API(320850, 1); // epoll error
|
|||
|
MTLOG_ERROR("epoll ctrl failed, fd: %d, op: %d, errno: %d", fd, op, errno);
|
|||
|
epoll_assert(0);
|
|||
|
return false;
|
|||
|
}
|
|||
|
item->SetListenEvents(new_events);
|
|||
|
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
/**
|
|||
|
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD>epfd<EFBFBD><EFBFBD><EFBFBD><EFBFBD>epctrl, <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD><EFBFBD>, <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
*/
|
|||
|
bool EpollProxy::EpollAddObj(EpollerObj* obj)
|
|||
|
{
|
|||
|
if (NULL == obj)
|
|||
|
{
|
|||
|
MTLOG_ERROR("epobj input invalid, %p", obj);
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
FdRef* item = FdRefGet(obj->GetOsfd());
|
|||
|
if (NULL == item)
|
|||
|
{
|
|||
|
MT_ATTR_API(320851, 1); // fd error
|
|||
|
MTLOG_ERROR("epfd ref not find, failed, fd: %d", obj->GetOsfd());
|
|||
|
epoll_assert(0);
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
// <20><>ͬ<EFBFBD>Ļص<C4BB>״̬, <20><>ͬ<EFBFBD>ķ<EFBFBD>ʽ<EFBFBD><CABD><EFBFBD><EFBFBD> del <20>¼<EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӹ<EFBFBD><D3B8>÷<EFBFBD>ʽ<EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
int ret = obj->EpollCtlAdd(item);
|
|||
|
if (ret < 0)
|
|||
|
{
|
|||
|
MTLOG_ERROR("epoll ctrl callback failed, fd: %d, obj: %p", obj->GetOsfd(), obj);
|
|||
|
epoll_assert(0);
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/**
|
|||
|
* @brief <EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>socket<EFBFBD>Ƴ<EFBFBD>epoll<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
* @param fdset <EFBFBD>߳<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>socket<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
* @return true <EFBFBD>ɹ<EFBFBD>, false ʧ<EFBFBD><EFBFBD>
|
|||
|
*/
|
|||
|
bool EpollProxy::EpollDelObj(EpollerObj* obj)
|
|||
|
{
|
|||
|
if (NULL == obj)
|
|||
|
{
|
|||
|
MTLOG_ERROR("fdobj input invalid, %p", obj);
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
FdRef* item = FdRefGet(obj->GetOsfd());
|
|||
|
if (NULL == item)
|
|||
|
{
|
|||
|
MT_ATTR_API(320851, 1); // fd error
|
|||
|
MTLOG_ERROR("epfd ref not find, failed, fd: %d", obj->GetOsfd());
|
|||
|
epoll_assert(0);
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
// <20><>ͬ<EFBFBD>Ļص<C4BB>״̬, <20><>ͬ<EFBFBD>ķ<EFBFBD>ʽ<EFBFBD><CABD><EFBFBD><EFBFBD> del <20>¼<EFBFBD>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӹ<EFBFBD><D3B8>÷<EFBFBD>ʽ<EFBFBD>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
int ret = obj->EpollCtlDel(item);
|
|||
|
if (ret < 0)
|
|||
|
{
|
|||
|
MTLOG_ERROR("epoll ctrl callback failed, fd: %d, obj: %p", obj->GetOsfd(), obj);
|
|||
|
epoll_assert(0);
|
|||
|
return false;
|
|||
|
}
|
|||
|
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/**
|
|||
|
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD>ÿ<EFBFBD><EFBFBD>socket<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>½<EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD><EFBFBD><EFBFBD>Ϣ
|
|||
|
* @param evtfdnum <EFBFBD>յ<EFBFBD><EFBFBD>¼<EFBFBD><EFBFBD><EFBFBD>fd<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ
|
|||
|
*/
|
|||
|
void EpollProxy::EpollRcvEventList(int evtfdnum)
|
|||
|
{
|
|||
|
int ret = 0;
|
|||
|
int osfd = 0;
|
|||
|
int revents = 0;
|
|||
|
FdRef* item = NULL;
|
|||
|
EpollerObj* obj = NULL;
|
|||
|
|
|||
|
for (int i = 0; i < evtfdnum; i++)
|
|||
|
{
|
|||
|
osfd = _evtlist[i].data.fd;
|
|||
|
item = FdRefGet(osfd);
|
|||
|
if (NULL == item)
|
|||
|
{
|
|||
|
MT_ATTR_API(320851, 1); // fd error
|
|||
|
MTLOG_ERROR("epfd ref not find, failed, fd: %d", osfd);
|
|||
|
epoll_assert(0);
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
revents = _evtlist[i].events;
|
|||
|
obj = item->GetNotifyObj();
|
|||
|
if (NULL == obj)
|
|||
|
{
|
|||
|
MTLOG_ERROR("fd notify obj null, failed, fd: %d", osfd);
|
|||
|
EpollCtrlDel(osfd, (revents & (EPOLLIN | EPOLLOUT)));
|
|||
|
continue;
|
|||
|
}
|
|||
|
obj->SetRcvEvents(revents);
|
|||
|
|
|||
|
// 1. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <20><><EFBFBD>Ϻ<EFBFBD>ֱ<EFBFBD><D6B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
if (revents & (EPOLLERR | EPOLLHUP))
|
|||
|
{
|
|||
|
obj->HangupNotify();
|
|||
|
continue;
|
|||
|
}
|
|||
|
|
|||
|
// 2. <20>ɶ<EFBFBD><C9B6>¼<EFBFBD>, <20><>0<EFBFBD><30><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
if (revents & EPOLLIN) {
|
|||
|
ret = obj->InputNotify();
|
|||
|
if (ret != 0) {
|
|||
|
continue;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// 3. <20><>д<EFBFBD>¼<EFBFBD>, <20><>0<EFBFBD><30><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
if (revents & EPOLLOUT) {
|
|||
|
ret = obj->OutputNotify();
|
|||
|
if (ret != 0) {
|
|||
|
continue;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/**
|
|||
|
* @brief epoll_wait <EFBFBD>Լ<EFBFBD><EFBFBD>ַ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
*/
|
|||
|
void EpollProxy::EpollDispath()
|
|||
|
{
|
|||
|
int wait_time = EpollGetTimeout();
|
|||
|
int nfd = epoll_wait(_epfd, _evtlist, _maxfd, wait_time);
|
|||
|
if (nfd <= 0) {
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
EpollRcvEventList(nfd);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
/**
|
|||
|
* @brief <EFBFBD>ɶ<EFBFBD><EFBFBD>¼<EFBFBD>֪ͨ<EFBFBD>ӿ<EFBFBD>, <EFBFBD><EFBFBD><EFBFBD><EFBFBD>֪ͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܻ<EFBFBD><EFBFBD>ƻ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <EFBFBD><EFBFBD><EFBFBD>÷<EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
* @return 0 <EFBFBD><EFBFBD>fd<EFBFBD>ɼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD>; !=0 <EFBFBD><EFBFBD>fd<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ص<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
*/
|
|||
|
int EpollerObj::InputNotify()
|
|||
|
{
|
|||
|
MicroThread* thread = this->GetOwnerThread();
|
|||
|
if (NULL == thread)
|
|||
|
{
|
|||
|
epoll_assert(0);
|
|||
|
MTLOG_ERROR("Epoll fd obj, no thread ptr, wrong");
|
|||
|
return -1;
|
|||
|
}
|
|||
|
|
|||
|
// <20><><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD>ͬʱ<CDAC><CAB1><EFBFBD><EFBFBD>, <20><><EFBFBD>ظ<EFBFBD><D8B8><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
if (thread->HasFlag(MicroThread::IO_LIST))
|
|||
|
{
|
|||
|
MtFrame* frame = MtFrame::Instance();
|
|||
|
frame->RemoveIoWait(thread);
|
|||
|
frame->InsertRunable(thread);
|
|||
|
}
|
|||
|
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* @brief <EFBFBD><EFBFBD>д<EFBFBD>¼<EFBFBD>֪ͨ<EFBFBD>ӿ<EFBFBD>, <EFBFBD><EFBFBD><EFBFBD><EFBFBD>֪ͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܻ<EFBFBD><EFBFBD>ƻ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>, <EFBFBD><EFBFBD><EFBFBD>÷<EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
* @return 0 <EFBFBD><EFBFBD>fd<EFBFBD>ɼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD>; !=0 <EFBFBD><EFBFBD>fd<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ص<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
*/
|
|||
|
int EpollerObj::OutputNotify()
|
|||
|
{
|
|||
|
MicroThread* thread = this->GetOwnerThread();
|
|||
|
if (NULL == thread)
|
|||
|
{
|
|||
|
epoll_assert(0);
|
|||
|
MTLOG_ERROR("Epoll fd obj, no thread ptr, wrong");
|
|||
|
return -1;
|
|||
|
}
|
|||
|
|
|||
|
// <20><><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD>ͬʱ<CDAC><CAB1><EFBFBD><EFBFBD>, <20><><EFBFBD>ظ<EFBFBD><D8B8><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
if (thread->HasFlag(MicroThread::IO_LIST))
|
|||
|
{
|
|||
|
MtFrame* frame = MtFrame::Instance();
|
|||
|
frame->RemoveIoWait(thread);
|
|||
|
frame->InsertRunable(thread);
|
|||
|
}
|
|||
|
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* @brief <EFBFBD>쳣֪ͨ<EFBFBD>ӿ<EFBFBD>, <EFBFBD>ر<EFBFBD>fd<EFBFBD><EFBFBD><EFBFBD><EFBFBD>, thread<EFBFBD>ȴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ
|
|||
|
* @return <EFBFBD><EFBFBD><EFBFBD>Է<EFBFBD><EFBFBD><EFBFBD>ֵ, <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
*/
|
|||
|
int EpollerObj::HangupNotify()
|
|||
|
{
|
|||
|
MtFrame* frame = MtFrame::Instance();
|
|||
|
frame->EpollCtrlDel(this->GetOsfd(), this->GetEvents());
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD>epoll<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD><EFBFBD>Ļص<EFBFBD><EFBFBD>ӿ<EFBFBD>, <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD>EPOLLIN, ż<EFBFBD><EFBFBD>EPOLLOUT
|
|||
|
* @param args fd<EFBFBD><EFBFBD><EFBFBD>ö<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD>
|
|||
|
* @return 0 <EFBFBD>ɹ<EFBFBD>, < 0 ʧ<EFBFBD><EFBFBD>, Ҫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ع<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ״̬
|
|||
|
*/
|
|||
|
int EpollerObj::EpollCtlAdd(void* args)
|
|||
|
{
|
|||
|
MtFrame* frame = MtFrame::Instance();
|
|||
|
FdRef* fd_ref = (FdRef*)args;
|
|||
|
epoll_assert(fd_ref != NULL);
|
|||
|
|
|||
|
int osfd = this->GetOsfd();
|
|||
|
int new_events = this->GetEvents();
|
|||
|
|
|||
|
// ֪ͨ<CDA8><D6AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD>, FD֪ͨ<CDA8><D6AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϲ<EFBFBD><CFB2>Ḵ<EFBFBD><E1B8B4>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͻ<EFBFBD><CDBB><EFBFBD><EFBFBD>, <20>쳣log<6F><67>¼
|
|||
|
EpollerObj* old_obj = fd_ref->GetNotifyObj();
|
|||
|
if ((old_obj != NULL) && (old_obj != this))
|
|||
|
{
|
|||
|
MTLOG_ERROR("epfd ref conflict, fd: %d, old: %p, now: %p", osfd, old_obj, this);
|
|||
|
return -1;
|
|||
|
}
|
|||
|
fd_ref->SetNotifyObj(this);
|
|||
|
|
|||
|
// <20><><EFBFBD>ÿ<EFBFBD><C3BF>ܵ<EFBFBD>epoll ctl<74>ӿ<EFBFBD>, <20><><EFBFBD><EFBFBD>epoll ctrlϸ<6C><CFB8>
|
|||
|
if (!frame->EpollCtrlAdd(osfd, new_events))
|
|||
|
{
|
|||
|
MTLOG_ERROR("epfd ref add failed, log");
|
|||
|
fd_ref->SetNotifyObj(old_obj);
|
|||
|
return -2;
|
|||
|
}
|
|||
|
|
|||
|
return 0;
|
|||
|
}
|
|||
|
|
|||
|
/**
|
|||
|
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD>epoll<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD><EFBFBD>Ļص<EFBFBD><EFBFBD>ӿ<EFBFBD>, <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD>EPOLLIN, ż<EFBFBD><EFBFBD>EPOLLOUT
|
|||
|
* @param args fd<EFBFBD><EFBFBD><EFBFBD>ö<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD>
|
|||
|
* @return 0 <EFBFBD>ɹ<EFBFBD>, < 0 ʧ<EFBFBD><EFBFBD>, Ҫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ع<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ״̬
|
|||
|
*/
|
|||
|
int EpollerObj::EpollCtlDel(void* args)
|
|||
|
{
|
|||
|
MtFrame* frame = MtFrame::Instance();
|
|||
|
FdRef* fd_ref = (FdRef*)args;
|
|||
|
epoll_assert(fd_ref != NULL);
|
|||
|
|
|||
|
int osfd = this->GetOsfd();
|
|||
|
int events = this->GetEvents();
|
|||
|
|
|||
|
// ֪ͨ<CDA8><D6AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD>, FD֪ͨ<CDA8><D6AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϲ<EFBFBD><CFB2>Ḵ<EFBFBD><E1B8B4>, <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͻ<EFBFBD><CDBB><EFBFBD><EFBFBD>, <20>쳣log<6F><67>¼
|
|||
|
EpollerObj* old_obj = fd_ref->GetNotifyObj();
|
|||
|
if (old_obj != this)
|
|||
|
{
|
|||
|
MTLOG_ERROR("epfd ref conflict, fd: %d, old: %p, now: %p", osfd, old_obj, this);
|
|||
|
return -1;
|
|||
|
}
|
|||
|
fd_ref->SetNotifyObj(NULL);
|
|||
|
|
|||
|
// <20><><EFBFBD>ÿ<EFBFBD><C3BF>ܵ<EFBFBD>epoll ctl<74>ӿ<EFBFBD>, <20><><EFBFBD><EFBFBD>epoll ctrlϸ<6C><CFB8>
|
|||
|
if (!frame->EpollCtrlDelRef(osfd, events, false)) // <20><><EFBFBD><EFBFBD><EFBFBD>з<EFBFBD><D0B7><EFBFBD>, <20>״<EFBFBD><D7B4><EFBFBD><EFBFBD><EFBFBD>, <20>رյ<D8B1>
|
|||
|
{
|
|||
|
MTLOG_ERROR("epfd ref del failed, log");
|
|||
|
fd_ref->SetNotifyObj(old_obj);
|
|||
|
return -2;
|
|||
|
}
|
|||
|
|
|||
|
return 0;
|
|||
|
|
|||
|
}
|
|||
|
|
|||
|
|