Micro_thread: convert encoding of source files and remove chinese comments.

This commit is contained in:
logwang 2017-11-20 22:39:00 +08:00
parent ef39c58b67
commit 35a813994b
36 changed files with 1137 additions and 5986 deletions

View File

@ -20,17 +20,20 @@
########MAKEFILE##########
ifeq ($(FF_PATH),)
$(error variable FF_PATH is not set)
$(error variable FF_PATH is not set)
endif
ifeq ($(FF_DPDK),)
FF_DPDK= $(FF_PATH)/dpdk/x86_64-native-linuxapp-gcc
endif
DEBUG= -g
BINARY = libmt.a
FF_LIB=$(FF_PATH)/libfstack.a
DPDK_LIBS+= -L${FF_PATH}/lib -L${FF_DPDK}/lib -Wl,--whole-archive,-lfstack,--no-whole-archive
DPDK_LIBS+= -Wl,--whole-archive -lrte_pmd_vmxnet3_uio -lrte_pmd_i40e -lrte_pmd_ixgbe -lrte_pmd_e1000 -lrte_pmd_ring
DPDK_LIBS+= -Wl,--whole-archive -lrte_hash -lrte_kvargs -Wl,-lrte_mbuf -lethdev -lrte_eal -Wl,-lrte_mempool
DPDK_LIBS+= -lrte_ring -lrte_cmdline -lrte_cfgfile -lrte_kni -lrte_timer -Wl,-lrte_pmd_virtio
DPDK_LIBS+= -Wl,--no-whole-archive -lrt -lm -ldl -lcrypto -pthread
FF_LIBS+= -L${FF_PATH}/lib -L${FF_DPDK}/lib -Wl,--whole-archive,-lfstack,--no-whole-archive
FF_LIBS+= -Wl,--whole-archive -lrte_pmd_vmxnet3_uio -lrte_pmd_i40e -lrte_pmd_ixgbe -lrte_pmd_e1000 -lrte_pmd_ring
FF_LIBS+= -Wl,--whole-archive -lrte_hash -lrte_kvargs -Wl,-lrte_mbuf -lethdev -lrte_eal -Wl,-lrte_mempool
FF_LIBS+= -lrte_ring -lrte_cmdline -lrte_cfgfile -lrte_kni -lrte_timer -Wl,-lrte_pmd_virtio
FF_LIBS+= -Wl,--no-whole-archive -lrt -lm -ldl -lcrypto -pthread
# Comment the following line if you are not using the gnu c compiler
#C_ARGS = -Wall -g -fPIC -D_DEBUG
@ -91,9 +94,9 @@ LIB_OBJ = micro_thread.o kqueue_proxy.o arch_ctx.o mt_session.o mt_notify.o mt_a
libmt.a: $(LIB_OBJ)
@echo -e Linking $(CYAN)$@$(RESET) ...$(RED)
@-rm -f $@
@ar crs $@ $^ $(FST_LIB) $(CRESET)
@ar crs $@ $^ $(CRESET)
@chmod +x $@
echo: echo.o libmt.a
@echo -e Compile $(CYAN)$@$(RESET) ...$(RED)
@$(CC) -O -gdwarf-2 -o $@ $^ -lstdc++ -ldl -lm $(DPDK_LIBS) $(CRESET)
@$(CC) -O -gdwarf-2 -o $@ $^ -lstdc++ -ldl -lm $(FF_LIBS) $(CRESET)

View File

@ -1,561 +0,0 @@
/**
* 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
*/
EpollProxy::EpollProxy()
{
_maxfd = EpollProxy::DEFAULT_MAX_FD_NUM;
_epfd = -1;
_evtlist = NULL;
_eprefs = NULL;
}
/**
* @brief epoll初始化,
*/
int EpollProxy::InitEpoll(int max_num)
{
int rc = 0;
if (max_num > _maxfd) // 如果设置的数目较大, 则调整最大fd数目
{
_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反初始化
*/
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 线socket送入epoll管理
* @param fdset 线socket集合
* @return true , false , ,
*/
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 线socket移除epoll管理
* @param fdset 线socket集合
* @return true , false
*/
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 epfd更新epctrl,
*/
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;
}
// 更新引用计数, 部分流程会依赖该计数, 失败要回滚
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 epfd更新epctrl,
*/
bool EpollProxy::EpollCtrlDel(int fd, int events)
{
return EpollCtrlDelRef(fd, events, false);
}
/**
* @brief epfd更新epctrl, , , 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 失败不回滚处理
int old_events = item->GetListenEvents();
int new_events = old_events &~ events; // 默认情况
// 如果要按引用删除, 需要核查是否满足删除条件
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 epfd更新epctrl, , 退
*/
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;
}
// 不同的回调状态, 不同的方式处理 del 事件, 屏蔽连接复用方式的处理复杂性
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 线socket移除epoll管理
* @param fdset 线socket集合
* @return true , false
*/
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;
}
// 不同的回调状态, 不同的方式处理 del 事件, 屏蔽连接复用方式的处理复杂性
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 socket的最新接收事件信息
* @param evtfdnum fd集合数目
*/
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. 错误处理, 完毕后直接跳出
if (revents & (EPOLLERR | EPOLLHUP))
{
obj->HangupNotify();
continue;
}
// 2. 可读事件, 非0返回值会跳出
if (revents & EPOLLIN) {
ret = obj->InputNotify();
if (ret != 0) {
continue;
}
}
// 3. 可写事件, 非0返回值会跳出
if (revents & EPOLLOUT) {
ret = obj->OutputNotify();
if (ret != 0) {
continue;
}
}
}
}
/**
* @brief epoll_wait
*/
void EpollProxy::EpollDispath()
{
int wait_time = EpollGetTimeout();
int nfd = epoll_wait(_epfd, _evtlist, _maxfd, wait_time);
if (nfd <= 0) {
return;
}
EpollRcvEventList(nfd);
}
/**
* @brief , ,
* @return 0 fd可继续处理其它事件; !=0 fd需跳出回调处理
*/
int EpollerObj::InputNotify()
{
MicroThread* thread = this->GetOwnerThread();
if (NULL == thread)
{
epoll_assert(0);
MTLOG_ERROR("Epoll fd obj, no thread ptr, wrong");
return -1;
}
// 多个事件同时到达, 防重复操作
if (thread->HasFlag(MicroThread::IO_LIST))
{
MtFrame* frame = MtFrame::Instance();
frame->RemoveIoWait(thread);
frame->InsertRunable(thread);
}
return 0;
}
/**
* @brief , ,
* @return 0 fd可继续处理其它事件; !=0 fd需跳出回调处理
*/
int EpollerObj::OutputNotify()
{
MicroThread* thread = this->GetOwnerThread();
if (NULL == thread)
{
epoll_assert(0);
MTLOG_ERROR("Epoll fd obj, no thread ptr, wrong");
return -1;
}
// 多个事件同时到达, 防重复操作
if (thread->HasFlag(MicroThread::IO_LIST))
{
MtFrame* frame = MtFrame::Instance();
frame->RemoveIoWait(thread);
frame->InsertRunable(thread);
}
return 0;
}
/**
* @brief , fd侦听, thread等待处理超时
* @return ,
*/
int EpollerObj::HangupNotify()
{
MtFrame* frame = MtFrame::Instance();
frame->EpollCtrlDel(this->GetOsfd(), this->GetEvents());
return 0;
}
/**
* @brief epoll侦听事件的回调接口, EPOLLIN, EPOLLOUT
* @param args fd引用对象的指针
* @return 0 , < 0 ,
*/
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();
// 通知对象需要更新, FD通知对象理论上不会复用, 这里做冲突检查, 异常log记录
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);
// 调用框架的epoll ctl接口, 屏蔽epoll ctrl细节
if (!frame->EpollCtrlAdd(osfd, new_events))
{
MTLOG_ERROR("epfd ref add failed, log");
fd_ref->SetNotifyObj(old_obj);
return -2;
}
return 0;
}
/**
* @brief epoll侦听事件的回调接口, EPOLLIN, EPOLLOUT
* @param args fd引用对象的指针
* @return 0 , < 0 ,
*/
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();
// 通知对象需要更新, FD通知对象理论上不会复用, 这里做冲突检查, 异常log记录
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);
// 调用框架的epoll ctl接口, 屏蔽epoll ctrl细节
if (!frame->EpollCtrlDelRef(osfd, events, false)) // 引用有风险, 弊大于利, 关闭掉
{
MTLOG_ERROR("epfd ref del failed, log");
fd_ref->SetNotifyObj(old_obj);
return -2;
}
return 0;
}

View File

@ -1,434 +0,0 @@
/**
* 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.h
* @info epoll for micro thread manage
*/
#ifndef _EPOLL_PROXY___
#define _EPOLL_PROXY___
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/uio.h>
#include <sys/time.h>
#include <sys/queue.h>
#include <sys/resource.h>
#include <fcntl.h>
#include <signal.h>
#include <errno.h>
#include <sys/epoll.h>
#include <assert.h>
#include <set>
#include <vector>
using std::set;
using std::vector;
#define epoll_assert(statement)
//#define epoll_assert(statement) assert(statement)
namespace NS_MICRO_THREAD {
/******************************************************************************/
/* 操作系统头文件适配定义 */
/******************************************************************************/
/**
* @brief add more detail for linux <sys/queue.h>, freebsd and University of California
* @info queue.h version 8.3 (suse) diff version 8.5 (tlinux)
*/
#ifndef TAILQ_CONCAT
#define TAILQ_EMPTY(head) ((head)->tqh_first == NULL)
#define TAILQ_FIRST(head) ((head)->tqh_first)
#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
#define TAILQ_LAST(head, headname) \
(*(((struct headname *)((head)->tqh_last))->tqh_last))
#define TAILQ_FOREACH(var, head, field) \
for ((var) = TAILQ_FIRST((head)); \
(var); \
(var) = TAILQ_NEXT((var), field))
#define TAILQ_CONCAT(head1, head2, field) \
do { \
if (!TAILQ_EMPTY(head2)) { \
*(head1)->tqh_last = (head2)->tqh_first; \
(head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \
(head1)->tqh_last = (head2)->tqh_last; \
TAILQ_INIT((head2)); \
} \
} while (0)
#endif
#ifndef TAILQ_FOREACH_SAFE // tlinux no this define
#define TAILQ_FOREACH_SAFE(var, head, field, tvar) \
for ((var) = TAILQ_FIRST((head)); \
(var) && ((tvar) = TAILQ_NEXT((var), field), 1); \
(var) = (tvar))
#endif
/******************************************************************************/
/* Epoll proxy 定义与实现部分 */
/******************************************************************************/
class EpollProxy;
class MicroThread;
/**
* @brief epoll通知对象基类定义
*/
class EpollerObj
{
protected:
int _fd; ///< 系统FD 或 socket
int _events; ///< 监听的事件类型
int _revents; ///< 收到的事件类型
int _type; ///< 工厂类别定义
MicroThread* _thread; ///< 关联线程指针对象
public:
TAILQ_ENTRY(EpollerObj) _entry; ///< 关联微线程的管理入口
/**
* @brief
*/
explicit EpollerObj(int fd = -1) {
_fd = fd;
_events = 0;
_revents = 0;
_type = 0;
_thread = NULL;
};
virtual ~EpollerObj(){};
/**
* @brief , ,
* @return 0 fd可继续处理其它事件; !=0 fd需跳出回调处理
*/
virtual int InputNotify();
/**
* @brief , ,
* @return 0 fd可继续处理其它事件; !=0 fd需跳出回调处理
*/
virtual int OutputNotify();
/**
* @brief
* @return ,
*/
virtual int HangupNotify();
/**
* @brief epoll侦听事件的回调接口, EPOLLIN, EPOLLOUT
* @param args fd引用对象的指针
* @return 0 , < 0 ,
*/
virtual int EpollCtlAdd(void* args);
/**
* @brief epoll侦听事件的回调接口, EPOLLIN, EPOLLOUT
* @param args fd引用对象的指针
* @return 0 , < 0 ,
*/
virtual int EpollCtlDel(void* args);
/**
* @brief fd打开可读事件侦听
*/
void EnableInput() { _events |= EPOLLIN; };
/**
* @brief fd打开可写事件侦听
*/
void EnableOutput() { _events |= EPOLLOUT; };
/**
* @brief fd关闭可读事件侦听
*/
void DisableInput() { _events &= ~EPOLLIN; };
/**
* @brief fd关闭可写事件侦听
*/
void DisableOutput() { _events &= ~EPOLLOUT; };
/**
* @brief socket设置读取封装
*/
int GetOsfd() { return _fd; };
void SetOsfd(int fd) { _fd = fd; };
/**
* @brief 访
*/
int GetEvents() { return _events; };
void SetRcvEvents(int revents) { _revents = revents; };
int GetRcvEvents() { return _revents; };
/**
* @brief ,
*/
int GetNtfyType() { return _type; };
virtual void Reset() {
_fd = -1;
_events = 0;
_revents = 0;
_type = 0;
_thread = NULL;
};
/**
* @brief 线
* @param thread 线
*/
void SetOwnerThread(MicroThread* thread) { _thread = thread; };
MicroThread* GetOwnerThread() { return _thread; };
};
typedef TAILQ_HEAD(__EpFdList, EpollerObj) EpObjList; ///< 高效的双链管理
typedef struct epoll_event EpEvent; ///< 重定义一下epoll event
/**
* @brief EPOLL支持同一FD多个线程侦听, ,
* @info , , , 20150623
*/
class FdRef
{
private:
int _wr_ref; ///< 监听写的引用计数
int _rd_ref; ///< 监听读的引用计数
int _events; ///< 当前正在侦听的事件列表
int _revents; ///< 当前该fd收到的事件信息, 仅在epoll_wait后处理中有效
EpollerObj* _epobj; ///< 单独注册调度器对象一个fd关联一个对象
public:
/**
* @brief
*/
FdRef() {
_wr_ref = 0;
_rd_ref = 0;
_events = 0;
_revents = 0;
_epobj = NULL;
};
~FdRef(){};
/**
* @brief
*/
void SetListenEvents(int events) {
_events = events;
};
int GetListenEvents() {
return _events;
};
/**
* @brief
*/
void SetNotifyObj(EpollerObj* ntfy) {
_epobj = ntfy;
};
EpollerObj* GetNotifyObj() {
return _epobj;
};
/**
* @brief
*/
void AttachEvents(int event) {
if (event & EPOLLIN) {
_rd_ref++;
}
if (event & EPOLLOUT){
_wr_ref++;
}
};
void DetachEvents(int event) {
if (event & EPOLLIN) {
if (_rd_ref > 0) {
_rd_ref--;
} else {
_rd_ref = 0;
}
}
if (event & EPOLLOUT){
if (_wr_ref > 0) {
_wr_ref--;
} else {
_wr_ref = 0;
}
}
};
/**
* @brief
*/
int ReadRefCnt() { return _rd_ref; };
int WriteRefCnt() { return _wr_ref; };
};
/**
* @brief EPOLL代理, epoll操作与epoll全局数据
*/
class EpollProxy
{
public:
static const int DEFAULT_MAX_FD_NUM = 100000; ///< 默认最大监控的fd
private:
int _epfd; ///< epoll 主句柄
int _maxfd; ///< 最大的文件句柄数
EpEvent* _evtlist; ///< epoll返回给用户的事件列表指针
FdRef* _eprefs; ///< 用户监听的事件本地管理数组
public:
/**
* @brief
*/
EpollProxy();
virtual ~EpollProxy(){};
/**
* @brief epoll初始化与终止处理,
* @param max_num fd数目
*/
int InitEpoll(int max_num);
void TermEpoll(void);
/**
* @brief epoll_wait
* @return , MS
*/
virtual int EpollGetTimeout(void) { return 0;};
/**
* @brief epoll
* @param fdlist , socket集合
* @param fd socket,
* @param timeout ,
* @return true , false
*/
virtual bool EpollSchedule(EpObjList* fdlist, EpollerObj* fd, int timeout) { return false;};
/**
* @brief 线socket送入epoll管理
* @param fdset 线socket集合
* @return true , false
*/
bool EpollAdd(EpObjList& fdset);
/**
* @brief 线socket移除epoll管理
* @param fdset 线socket集合
* @return true , false
*/
bool EpollDel(EpObjList& fdset);
/**
* @brief epoll_wait
*/
void EpollDispath(void);
/**
* @brief fd注册,
* @param fd
* @param obj epoll回调对象
*/
bool EpollAddObj(EpollerObj* obj);
/**
* @brief fd注册,
* @param fd
* @param obj epoll回调对象
*/
bool EpollDelObj(EpollerObj* obj);
/**
* @brief epoll ctl的处理与当前监听事件的记录,
* @param fd
* @param new_events
*/
bool EpollCtrlAdd(int fd, int new_events);
/**
* @brief epoll ctl的处理与当前监听事件的记录,
* @param fd
* @param new_events
*/
bool EpollCtrlDel(int fd, int new_events);
bool EpollCtrlDelRef(int fd, int new_events, bool use_ref);
/**
* @brief fd获取本地引用的结构, fd生成策略,
* @param fd
* @return , NULL
*/
FdRef* FdRefGet(int fd) {
return ((fd >= _maxfd) || (fd < 0)) ? (FdRef*)NULL : &_eprefs[fd];
};
/**
* @brief ,
* @param fd
* @param obj
*/
void EpollNtfyReg(int fd, EpollerObj* obj) {
FdRef* ref = FdRefGet(fd);
if (ref) {
ref->SetNotifyObj(obj);
}
};
protected:
/**
* @brief socket的最新接收事件信息
* @param evtfdnum fd集合数目
*/
void EpollRcvEventList(int evtfdnum);
};
}//NAMESPCE
#endif

View File

@ -19,8 +19,6 @@
/**
* @filename hash_list.h
* @info hash类, hash存储实现; hash映射,
* , , ,
* @time 2013-06-11
*/
@ -35,94 +33,59 @@
namespace NS_MICRO_THREAD {
/**
* @brief Hash存放元素的基类,
*/
class HashKey
{
private:
HashKey* _next_entry; ///< 开链hash的链接元素
uint32_t _hash_value; ///< hash value信息, 节约比较的时间
void* _data_ptr; ///< hash data数据指针, 可key - value 聚合存储
HashKey* _next_entry;
uint32_t _hash_value;
void* _data_ptr;
public:
friend class HashList; ///< hash表可以直接访问next指针
friend class HashList;
/**
* @brief
*/
HashKey():_next_entry(NULL), _hash_value(0), _data_ptr(NULL) {};
virtual ~HashKey(){};
/**
* @brief hash算法, key的hash值
* @return hash值
*/
virtual uint32_t HashValue() = 0;
/**
* @brief cmp方法, ID下, key比较
* @return hash值
*/
virtual int HashCmp(HashKey* rhs) = 0;
/**
* @brief , , ,
*/
virtual void HashIterate() {
return;
};
/**
* @brief
*/
void* GetDataPtr() {
return _data_ptr;
};
void SetDataPtr(void* data) {
_data_ptr = data;
};
};
/**
* @brief Hash管理类, hash, hash函数,
*/
class HashList
{
public:
/**
* @brief
*/
explicit HashList(int max = 100000) {
explicit HashList(int max = 100000) {
_max = GetMaxPrimeNum((max > 2) ? max : 100000);
_buckets = (HashKey**)calloc(_max, sizeof(HashKey*));
_count = 0;
};
virtual ~HashList() {
if (_buckets) {
free(_buckets);
_buckets = NULL;
}
_buckets = (HashKey**)calloc(_max, sizeof(HashKey*));
_count = 0;
};
};
virtual ~HashList() {
if (_buckets) {
free(_buckets);
_buckets = NULL;
}
_count = 0;
};
/**
* @brief hash的元素个数
* @return
*/
int HashSize() {
return _count;
};
/**
* @brief hash插入元素, , remove
* @param key , ,
* @return 0 , -1 , -2
* @brief hash insert key.
*/
int HashInsert(HashKey* key) {
if (!key || !_buckets) {
@ -144,9 +107,7 @@ public:
}
/**
* @brief hash查找元素
* @param key key指针
* @return , NULL表明无数据
* @brief hash lookup key.
*/
HashKey* HashFind(HashKey* key) {
if (!key || !_buckets) {
@ -171,9 +132,7 @@ public:
}
/**
* @brief hash查找元素
* @param key key指针
* @return , NULL表明无数据
* @brief hash lookup key.
*/
void* HashFindData(HashKey* key) {
HashKey* item = HashFind(key);
@ -186,8 +145,7 @@ public:
/**
* @brief hash删除元素
* @param key key指针
* @brief hash remove key.
*/
void HashRemove(HashKey* key) {
if (!key || !_buckets) {
@ -215,7 +173,7 @@ public:
}
/**
* @brief hash遍历元素,
* @brief hash loop.
*/
void HashForeach() {
if (!_buckets) {
@ -231,7 +189,7 @@ public:
}
/**
* @brief hash清理遍历, ,
* @brief traverse hash list, low performance, only for remove.
*/
HashKey* HashGetFirst() {
if (!_buckets) {
@ -249,38 +207,35 @@ public:
private:
/**
* @brief
*/
int GetMaxPrimeNum(int num)
{
int sqrt_value = (int)sqrt(num);
for (int i = num; i > 0; i--)
{
int flag = 1;
for (int k = 2; k <= sqrt_value; k++)
{
if (i % k == 0)
{
flag = 0;
break;
}
}
int sqrt_value = (int)sqrt(num);
for (int i = num; i > 0; i--)
{
int flag = 1;
for (int k = 2; k <= sqrt_value; k++)
{
if (i % k == 0)
{
flag = 0;
break;
}
}
if (flag == 1)
{
return i;
}
}
if (flag == 1)
{
return i;
}
}
return 0;
return 0;
};
private:
HashKey** _buckets; ///< 桶指针
int _count; ///< 有效元素个数
int _max; ///< 最大节点个数
HashKey** _buckets;
int _count;
int _max;
};
}

View File

@ -19,7 +19,7 @@
/**
* @filename heap.h
* @info , , std::make_heap
* @info flexible insert and delete heap, if no random deletion, use std::make_heap
* @time 2013-06-11
*/
@ -36,62 +36,36 @@
namespace NS_MICRO_THREAD {
class HeapEntry; // 堆元素类, 继承实现扩展
class HeapList; // 堆管理类, 通用
class HeapEntry;
class HeapList;
/**
* @brief , ,
* @brief definition of heap elements for minimum heap
*/
class HeapEntry
{
private:
int _index; ///< 堆元素下标, 利于快速索引删除操作
int _index;
public:
friend class HeapList;
friend class HeapList;
/**
* @brief
*/
HeapEntry():_index(0){};
virtual ~HeapEntry(){};
HeapEntry():_index(0){};
virtual ~HeapEntry(){};
/**
* @brief , , ,
* @return
*/
virtual unsigned long long HeapValue() = 0;
/**
* @brief , , ,
*/
virtual void HeapIterate() {
return;
};
/**
* @brief
* @param list
* @return 0 ; -1 ; -2
*/
inline int InsertIntoHeap(HeapList* list);
/**
* @brief
* @param list
* @return 0 ; -1 ; -2
*/
inline int DeleteFromHeap(HeapList* list);
/**
* @brief , 使
* @return
*/
inline int GetIndex() {
return _index;
};
inline int GetIndex() {
return _index;
};
private:
@ -105,50 +79,42 @@ private:
}
};
inline void SetIndex(int index) {
_index = index;
};
inline void SetIndex(int index) {
_index = index;
};
};
/**
* @brief ,
* @brief minimum heap queue.
*/
class HeapList
{
private:
HeapEntry** _list; // 堆元素的指针数组, 目前定长
int _max; // 堆可管理最大元素个数
int _count; // 堆已经管理的元素个数
HeapEntry** _list;
int _max;
int _count;
public:
/**
* @brief
*/
explicit HeapList(int max = 100000) {
explicit HeapList(int max = 100000) {
_max = (max > 0) ? max : 100000;
_list = (HeapEntry**)malloc (sizeof(HeapEntry*) * (_max+1));
heap_assert(_list);
memset(_list, 0, sizeof(HeapEntry*) * (_max+1));
_count = 0;
};
virtual ~HeapList() {
if (_list) {
free(_list);
_list = NULL;
}
_list = (HeapEntry**)malloc (sizeof(HeapEntry*) * (_max+1));
heap_assert(_list);
memset(_list, 0, sizeof(HeapEntry*) * (_max+1));
_count = 0;
};
virtual ~HeapList() {
if (_list) {
free(_list);
_list = NULL;
}
_max = 0;
_count = 0;
};
};
/**
* @brief heap的大小,
* @param size
* @return 0 ; -1
*/
int HeapResize(int size) {
if (_max >= size) {
return 0;
@ -166,270 +132,199 @@ public:
return 0;
};
/**
* @brief
* @param entry
* @return 0 ; -1 ; -2
*/
int HeapPush(HeapEntry* entry);
int HeapPush(HeapEntry* entry);
/**
* @brief ,
* @return , NULL
*/
HeapEntry* HeapPop();
HeapEntry* HeapPop();
/**
* @brief
* @param entry
* @return 0 ; -1 ; -2
*/
int HeapDelete(HeapEntry* entry);
int HeapDelete(HeapEntry* entry);
/**
* @brief , 2,
*/
void HeapForeach();
void HeapForeach();
/**
* @brief
* @return
*/
int HeapSize() {
return _count;
};
/**
* @brief ,
* @return , NULL
*/
HeapEntry* HeapTop() {
return (_count > 0) ? _list[1] : NULL;
};
private:
/**
* @brief
* @return true
*/
bool HeapFull() {
return (_count >= _max);
};
bool HeapFull() {
return (_count >= _max);
};
/**
* @brief
* @return true
*/
bool HeapEmpty() {
return (_count == 0);
};
/**
* @brief ,
*/
void HeapUp();
bool HeapEmpty() {
return (_count == 0);
};
/**
* @brief ,
*/
void HeapDown(int index);
void HeapUp();
void HeapDown(int index);
};
/**
* @brief ,
*/
inline void HeapList::HeapUp()
{
for (int pos = _count; pos > 0; pos = pos/2)
{
if (pos/2 < 1) // pos == 1 已经到顶, 0 属于保留
{
break;
}
for (int pos = _count; pos > 0; pos = pos/2)
{
if (pos/2 < 1) // pos == 1 peaked, 0 reserved.
{
break;
}
if (_list[pos]->HeapValueCmp(_list[pos/2]) < 0)
{
HeapEntry* tmp = _list[pos/2];
_list[pos/2] = _list[pos];
_list[pos] = tmp;
{
HeapEntry* tmp = _list[pos/2];
_list[pos/2] = _list[pos];
_list[pos] = tmp;
_list[pos]->SetIndex(pos);
_list[pos/2]->SetIndex(pos/2);
}
else
{
break;
}
}
_list[pos]->SetIndex(pos);
_list[pos/2]->SetIndex(pos/2);
}
else
{
break;
}
}
}
/**
* @brief ,
* @param index
*/
inline void HeapList::HeapDown(int index)
{
int min_son;
for (int pos = index; pos <= _count; pos = min_son)
{
if (pos*2 > _count) // pos是叶子节点了
{
break;
}
else if (pos*2 == _count)
{
min_son = pos*2;
}
else
{
int min_son;
for (int pos = index; pos <= _count; pos = min_son)
{
if (pos*2 > _count) // pos is a leaf node.
{
break;
}
else if (pos*2 == _count)
{
min_son = pos*2;
}
else
{
if (_list[pos*2+1]->HeapValueCmp(_list[pos*2]) < 0)
{
min_son = pos*2+1;
}
else
{
min_son = pos*2;
}
}
{
min_son = pos*2+1;
}
else
{
min_son = pos*2;
}
}
if (_list[pos]->HeapValueCmp(_list[min_son]) > 0)
{
HeapEntry* tmp = _list[min_son];
_list[min_son] = _list[pos];
_list[pos] = tmp;
if (_list[pos]->HeapValueCmp(_list[min_son]) > 0)
{
HeapEntry* tmp = _list[min_son];
_list[min_son] = _list[pos];
_list[pos] = tmp;
_list[pos]->SetIndex(pos);
_list[min_son]->SetIndex(min_son);
}
else
{
break;
}
}
_list[pos]->SetIndex(pos);
_list[min_son]->SetIndex(min_son);
}
else
{
break;
}
}
}
/**
* @brief
* @param entry
* @return 0 ; -1 ; -2
*/
inline int HeapList::HeapPush(HeapEntry* item)
{
if (HeapFull()) {
heap_assert(0); // 满, 理论上是可能的, 实际运行不太可能过10W
return -1;
}
if (HeapFull()) {
heap_assert(0); // it's possible in theory but not in fact.
return -1;
}
if (item->GetIndex() != 0) {
heap_assert(0); // 重复插入
heap_assert(0); // duplicated insertion.
return -2;
}
_count++;
_list[_count] = item;
_count++;
_list[_count] = item;
item->SetIndex(_count);
HeapUp();
HeapUp();
return 0;
return 0;
}
/**
* @brief ,
* @return , NULL
*/
inline HeapEntry* HeapList::HeapPop()
{
if (HeapEmpty()) {
return NULL;
}
if (HeapEmpty()) {
return NULL;
}
HeapEntry* top = _list[1]; // 0 保留
HeapEntry* top = _list[1]; // 0 reserved.
_list[1] = _list[_count];
_list[1] = _list[_count];
_list[1]->SetIndex(1);
_list[_count] = 0;
_count--;
HeapDown(1);
_count--;
HeapDown(1);
heap_assert(top->GetIndex() == 1);
top->SetIndex(0);
return top;
top->SetIndex(0);
return top;
}
/**
* @brief
* @param entry
* @return 0 ; -1 ; -2
*/
inline int HeapList::HeapDelete(HeapEntry* item)
{
if (HeapEmpty()) {
return -1;
}
if (HeapEmpty()) {
return -1;
}
int pos = item->GetIndex() ;
if ((pos > _count) ||(pos <= 0))
{
heap_assert(0); // 非法数据或重复删除
return -2;
}
int pos = item->GetIndex() ;
if ((pos > _count) ||(pos <= 0))
{
heap_assert(0); // duplicated deletion or illegal data.
return -2;
}
HeapEntry* del = _list[pos];
_list[pos] = _list[_count];
HeapEntry* del = _list[pos];
_list[pos] = _list[_count];
_list[pos]->SetIndex(pos);
_list[_count] = 0;
_count--;
_count--;
HeapDown(pos);
HeapDown(pos);
heap_assert(pos == del->GetIndex());
del->SetIndex(0);
return 0;
del->SetIndex(0);
return 0;
}
/**
* @brief , 2,
*/
inline void HeapList::HeapForeach()
{
int per = 1;
for (int i = 1; i <= _count; i++)
{
if (i >= per*2)
{
printf("\n");
per *=2;
}
printf("%llu ", _list[i]->HeapValue());
for (int i = 1; i <= _count; i++)
{
if (i >= per*2)
{
printf("\n");
per *=2;
}
printf("%llu ", _list[i]->HeapValue());
_list[i]->HeapIterate();
}
}
}
/**
* @brief
* @param list
* @return 0 ; -1 ; -2
*/
inline int HeapEntry::InsertIntoHeap(HeapList* list) {
return list->HeapPush(this);
};
/**
* @brief
* @param list
* @return 0 ; -1 ; -2
*/
inline int HeapEntry::DeleteFromHeap(HeapList* list) {
return list->HeapDelete(this);
};

View File

@ -26,10 +26,6 @@
using namespace NS_MICRO_THREAD;
/**
* @brief
*/
CTimerMng::CTimerMng(uint32_t max_item)
{
#define TIMER_MIN 100000
@ -42,10 +38,6 @@ CTimerMng::CTimerMng(uint32_t max_item)
_heap = new HeapList(max_item);
}
/**
* @brief
*/
CTimerMng::~CTimerMng()
{
if (_heap) {
@ -54,13 +46,6 @@ CTimerMng::~CTimerMng()
}
}
/**
* @brief
* @param timerable
* @param interval ms单位
* @return true,
*/
bool CTimerMng::start_timer(CTimerNotify* timerable, uint32_t interval)
{
if (!_heap || !timerable) {
@ -78,10 +63,6 @@ bool CTimerMng::start_timer(CTimerNotify* timerable, uint32_t interval)
return true;
}
/**
* @brief
* @param timerable
*/
void CTimerMng::stop_timer(CTimerNotify* timerable)
{
if (!_heap || !timerable) {
@ -92,9 +73,6 @@ void CTimerMng::stop_timer(CTimerNotify* timerable)
return;
}
/**
* @brief
*/
void CTimerMng::check_expired()
{
if (!_heap) {
@ -110,6 +88,3 @@ void CTimerMng::check_expired()
timer = dynamic_cast<CTimerNotify*>(_heap->HeapTop());
}
};

View File

@ -30,99 +30,52 @@
namespace NS_MICRO_THREAD
{
/**
* @brief
*/
class CTimerNotify : public HeapEntry
{
public:
/**
* @brief ,
*/
virtual void timer_notify() { return;};
/**
* @brief , , ,
* @return
*/
virtual unsigned long long HeapValue() {
return (unsigned long long)_time_expired;
};
/**
* @brief
*/
CTimerNotify() : _time_expired(0) {};
/**
* @brief
*/
virtual ~CTimerNotify(){};
/**
* @brief , ms
* @param expired ms单位
*/
void set_expired_time(uint64_t expired) {
_time_expired = expired;
};
/**
* @brief , ms
* @return ms单位
*/
uint64_t get_expired_time() {
return _time_expired;
};
private:
uint64_t _time_expired; // 绝对的超时时间ms单位
uint64_t _time_expired;
};
/**
* @brief
*/
class CTimerMng
{
public:
/**
* @brief
* @param max_item ()
*/
explicit CTimerMng(uint32_t max_item = 100000);
/**
* @brief
*/
~CTimerMng();
/**
* @brief
* @param timerable
* @param interval ms单位
* @return true,
*/
bool start_timer(CTimerNotify* timerable, uint32_t interval);
/**
* @brief
* @param timerable
*/
void stop_timer(CTimerNotify* timerable);
/**
* @brief
*/
void check_expired();
private:
HeapList* _heap; // 最小堆指针
HeapList* _heap;
};
}

View File

@ -39,34 +39,34 @@ KqueueProxy::KqueueProxy()
int KqueueProxy::InitKqueue(int max_num)
{
int rc = 0;
if (max_num > _maxfd)
{
_maxfd = max_num;
}
int rc = 0;
if (max_num > _maxfd)
{
_maxfd = max_num;
}
_kqfd = ff_kqueue();
if (_kqfd < 0)
{
rc = -1;
goto EXIT_LABEL;
}
_kqfd = ff_kqueue();
if (_kqfd < 0)
{
rc = -1;
goto EXIT_LABEL;
}
ff_fcntl(_kqfd, F_SETFD, FD_CLOEXEC);
ff_fcntl(_kqfd, F_SETFD, FD_CLOEXEC);
_kqrefs = new KqFdRef[_maxfd];
if (_kqrefs == NULL)
{
rc = -2;
goto EXIT_LABEL;
}
_kqrefs = new KqFdRef[_maxfd];
if (_kqrefs == NULL)
{
rc = -2;
goto EXIT_LABEL;
}
_evtlist = (KqEvent*)calloc(_maxfd, sizeof(KqEvent));
if (_evtlist == NULL)
{
rc = -3;
goto EXIT_LABEL;
}
_evtlist = (KqEvent*)calloc(_maxfd, sizeof(KqEvent));
if (_evtlist == NULL)
{
rc = -3;
goto EXIT_LABEL;
}
struct rlimit rlim;
memset(&rlim, 0, sizeof(rlim));
@ -115,20 +115,20 @@ void KqueueProxy::TermKqueue()
bool KqueueProxy::KqueueAdd(KqObjList& obj_list)
{
bool ret = true;
KqueuerObj *kqobj = NULL;
KqueuerObj *kqobj_error = NULL;
TAILQ_FOREACH(kqobj, &obj_list, _entry)
{
if (!KqueueAddObj(kqobj))
{
bool ret = true;
KqueuerObj *kqobj = NULL;
KqueuerObj *kqobj_error = NULL;
TAILQ_FOREACH(kqobj, &obj_list, _entry)
{
if (!KqueueAddObj(kqobj))
{
MTLOG_ERROR("kqobj add failed, fd: %d", kqobj->GetOsfd());
kqueue_assert(0);
kqobj_error = kqobj;
ret = false;
goto EXIT_LABEL;
}
}
}
}
EXIT_LABEL:
@ -167,303 +167,303 @@ bool KqueueProxy::KqueueDel(KqObjList& obj_list)
bool KqueueProxy::KqueueCtrlAdd(int fd, int events)
{
KqFdRef* item = KqFdRefGet(fd);
if (item == NULL)
{
KqFdRef* item = KqFdRefGet(fd);
if (item == NULL)
{
MT_ATTR_API(320851, 1); // fd error, wtf?
MTLOG_ERROR("kqfd ref not find, failed, fd: %d", fd);
kqueue_assert(0);
return false;
}
}
item->AttachEvents(events);
item->AttachEvents(events);
int old_events = item->GetListenEvents();
int new_events = old_events | events;
if (old_events == new_events)
{
return true;
}
KqEvent ke;
int ret;
if (old_events & KQ_EVENT_WRITE) {
EV_SET(&ke, fd, EVFILT_WRITE, EV_DELETE, 0, 0, NULL);
ret = ff_kevent(_kqfd, &ke, 1, NULL, 0, NULL);
if (ret == -1) {
// TODO, error check
item->DetachEvents(events);
kqueue_assert(0);
return false;
}
}
if (old_events & KQ_EVENT_READ) {
EV_SET(&ke, fd, EVFILT_READ, EV_DELETE, 0, 0, NULL);
ret = ff_kevent(_kqfd, &ke, 1, NULL, 0, NULL);
if (ret == -1) {
// TODO, error check
item->DetachEvents(events);
kqueue_assert(0);
return false;
}
}
if (events & KQ_EVENT_WRITE) {
EV_SET(&ke, fd, EVFILT_WRITE, EV_ADD, 0, 0, NULL);
ret = ff_kevent(_kqfd, &ke, 1, NULL, 0, NULL);
if (ret == -1) {
// TODO, error check
item->DetachEvents(events);
kqueue_assert(0);
return false;
}
}
if (events & KQ_EVENT_READ) {
EV_SET(&ke, fd, EVFILT_READ, EV_ADD, 0, 0, NULL);
ret = ff_kevent(_kqfd, &ke, 1, NULL, 0, NULL);
if (ret == -1) {
// TODO, error check
item->DetachEvents(events);
kqueue_assert(0);
return false;
}
}
int old_events = item->GetListenEvents();
int new_events = old_events | events;
if (old_events == new_events)
{
return true;
}
KqEvent ke;
int ret;
if (old_events & KQ_EVENT_WRITE) {
EV_SET(&ke, fd, EVFILT_WRITE, EV_DELETE, 0, 0, NULL);
ret = ff_kevent(_kqfd, &ke, 1, NULL, 0, NULL);
if (ret == -1) {
// TODO, error check
item->DetachEvents(events);
kqueue_assert(0);
return false;
}
}
if (old_events & KQ_EVENT_READ) {
EV_SET(&ke, fd, EVFILT_READ, EV_DELETE, 0, 0, NULL);
ret = ff_kevent(_kqfd, &ke, 1, NULL, 0, NULL);
if (ret == -1) {
// TODO, error check
item->DetachEvents(events);
kqueue_assert(0);
return false;
}
}
if (events & KQ_EVENT_WRITE) {
EV_SET(&ke, fd, EVFILT_WRITE, EV_ADD, 0, 0, NULL);
ret = ff_kevent(_kqfd, &ke, 1, NULL, 0, NULL);
if (ret == -1) {
// TODO, error check
item->DetachEvents(events);
kqueue_assert(0);
return false;
}
}
if (events & KQ_EVENT_READ) {
EV_SET(&ke, fd, EVFILT_READ, EV_ADD, 0, 0, NULL);
ret = ff_kevent(_kqfd, &ke, 1, NULL, 0, NULL);
if (ret == -1) {
// TODO, error check
item->DetachEvents(events);
kqueue_assert(0);
return false;
}
}
item->SetListenEvents(new_events);
item->SetListenEvents(new_events);
return true;
return true;
}
bool KqueueProxy::KqueueCtrlDel(int fd, int events)
{
return KqueueCtrlDelRef(fd, events, false);
return KqueueCtrlDelRef(fd, events, false);
}
bool KqueueProxy::KqueueCtrlDelRef(int fd, int events, bool use_ref)
{
KqFdRef* item = KqFdRefGet(fd);
if (item == NULL)
{
KqFdRef* item = KqFdRefGet(fd);
if (item == NULL)
{
MT_ATTR_API(320851, 1); // fd error
MTLOG_ERROR("kqfd ref not find, failed, fd: %d", fd);
kqueue_assert(0);
return false;
}
}
item->DetachEvents(events);
int old_events = item->GetListenEvents();
int new_events = old_events &~ events;
item->DetachEvents(events);
int old_events = item->GetListenEvents();
int new_events = old_events &~ events;
if (use_ref) {
new_events = old_events;
if (item->ReadRefCnt() == 0) {
new_events = new_events & ~KQ_EVENT_READ;
}
if (item->WriteRefCnt() == 0) {
new_events = new_events & ~KQ_EVENT_WRITE;
}
}
if (use_ref) {
new_events = old_events;
if (item->ReadRefCnt() == 0) {
new_events = new_events & ~KQ_EVENT_READ;
}
if (item->WriteRefCnt() == 0) {
new_events = new_events & ~KQ_EVENT_WRITE;
}
}
if (old_events == new_events)
{
return true;
}
KqEvent ke;
int ret;
if (old_events & KQ_EVENT_WRITE) {
EV_SET(&ke, fd, EVFILT_WRITE, EV_DELETE, 0, 0, NULL);
ret = ff_kevent(_kqfd, &ke, 1, NULL, 0, NULL);
if (ret == -1) {
kqueue_assert(0);
return false;
}
}
if (old_events & KQ_EVENT_READ) {
EV_SET(&ke, fd, EVFILT_READ, EV_DELETE, 0, 0, NULL);
ret = ff_kevent(_kqfd, &ke, 1, NULL, 0, NULL);
if (ret == -1) {
kqueue_assert(0);
return false;
}
}
if (old_events == new_events)
{
return true;
}
KqEvent ke;
int ret;
if (old_events & KQ_EVENT_WRITE) {
EV_SET(&ke, fd, EVFILT_WRITE, EV_DELETE, 0, 0, NULL);
ret = ff_kevent(_kqfd, &ke, 1, NULL, 0, NULL);
if (ret == -1) {
kqueue_assert(0);
return false;
}
}
if (old_events & KQ_EVENT_READ) {
EV_SET(&ke, fd, EVFILT_READ, EV_DELETE, 0, 0, NULL);
ret = ff_kevent(_kqfd, &ke, 1, NULL, 0, NULL);
if (ret == -1) {
kqueue_assert(0);
return false;
}
}
if (new_events & KQ_EVENT_WRITE) {
EV_SET(&ke, fd, EVFILT_WRITE, EV_ADD, 0, 0, NULL);
ret = ff_kevent(_kqfd, &ke, 1, NULL, 0, NULL);
if (ret == -1) {
kqueue_assert(0);
return false;
}
}
if (new_events & KQ_EVENT_READ) {
EV_SET(&ke, fd, EVFILT_READ, EV_ADD, 0, 0, NULL);
ret = ff_kevent(_kqfd, &ke, 1, NULL, 0, NULL);
if (ret == -1) {
kqueue_assert(0);
return false;
}
}
if (new_events & KQ_EVENT_WRITE) {
EV_SET(&ke, fd, EVFILT_WRITE, EV_ADD, 0, 0, NULL);
ret = ff_kevent(_kqfd, &ke, 1, NULL, 0, NULL);
if (ret == -1) {
kqueue_assert(0);
return false;
}
}
if (new_events & KQ_EVENT_READ) {
EV_SET(&ke, fd, EVFILT_READ, EV_ADD, 0, 0, NULL);
ret = ff_kevent(_kqfd, &ke, 1, NULL, 0, NULL);
if (ret == -1) {
kqueue_assert(0);
return false;
}
}
item->SetListenEvents(new_events);
item->SetListenEvents(new_events);
return true;
return true;
}
bool KqueueProxy::KqueueAddObj(KqueuerObj* obj)
{
if (obj == NULL)
{
if (obj == NULL)
{
MTLOG_ERROR("kqobj input invalid, %p", obj);
return false;
}
}
KqFdRef* item = KqFdRefGet(obj->GetOsfd());
if (item == NULL)
{
KqFdRef* item = KqFdRefGet(obj->GetOsfd());
if (item == NULL)
{
MT_ATTR_API(320851, 1); // fd error
MTLOG_ERROR("kqfd ref not find, failed, fd: %d", obj->GetOsfd());
kqueue_assert(0);
return false;
}
}
int ret = obj->KqueueCtlAdd(item);
if (ret < 0) {
int ret = obj->KqueueCtlAdd(item);
if (ret < 0) {
MTLOG_ERROR("kqueue ctrl callback failed, fd: %d, obj: %p", obj->GetOsfd(), obj);
kqueue_assert(0);
return false;
}
}
return true;
return true;
}
bool KqueueProxy::KqueueDelObj(KqueuerObj* obj)
{
if (obj == NULL)
{
if (obj == NULL)
{
MTLOG_ERROR("kqobj input invalid, %p", obj);
return false;
}
KqFdRef* item = KqFdRefGet(obj->GetOsfd());
if (item == NULL)
{
}
KqFdRef* item = KqFdRefGet(obj->GetOsfd());
if (item == NULL)
{
MT_ATTR_API(320851, 1); // fd error
MTLOG_ERROR("kqfd ref not find, failed, fd: %d", obj->GetOsfd());
kqueue_assert(0);
return false;
}
}
int ret = obj->KqueueCtlDel(item);
if (ret < 0) {
int ret = obj->KqueueCtlDel(item);
if (ret < 0) {
MTLOG_ERROR("kqueue ctrl callback failed, fd: %d, obj: %p", obj->GetOsfd(), obj);
kqueue_assert(0);
return false;
}
}
return true;
return true;
}
void KqueueProxy::KqueueRcvEventList(int evtfdnum)
{
int ret = 0;
int osfd = 0;
int revents = 0;
int tmp_evts = 0;
KqFdRef* item = NULL;
KqueuerObj* obj = NULL;
int ret = 0;
int osfd = 0;
int revents = 0;
int tmp_evts = 0;
KqFdRef* item = NULL;
KqueuerObj* obj = NULL;
for (int i = 0; i < evtfdnum; i++)
{
osfd = _evtlist[i].ident;
for (int i = 0; i < evtfdnum; i++)
{
osfd = _evtlist[i].ident;
item = KqFdRefGet(osfd);
if (item == NULL)
{
item = KqFdRefGet(osfd);
if (item == NULL)
{
MT_ATTR_API(320851, 1); // fd error
MTLOG_ERROR("kqfd ref not find, failed, fd: %d", osfd);
kqueue_assert(0);
continue;
}
tmp_evts = _evtlist[i].filter;
if (tmp_evts == EVFILT_READ) {
revents |= KQ_EVENT_READ;
}
if (tmp_evts == EVFILT_WRITE) {
revents |= KQ_EVENT_WRITE;
}
obj = item->GetNotifyObj();
if (obj == NULL)
{
}
tmp_evts = _evtlist[i].filter;
if (tmp_evts == EVFILT_READ) {
revents |= KQ_EVENT_READ;
}
if (tmp_evts == EVFILT_WRITE) {
revents |= KQ_EVENT_WRITE;
}
obj = item->GetNotifyObj();
if (obj == NULL)
{
MTLOG_ERROR("fd notify obj null, failed, fd: %d", osfd);
KqueueCtrlDel(osfd, (revents & (KQ_EVENT_READ | KQ_EVENT_WRITE)));
continue;
}
obj->SetRcvEvents(revents);
}
obj->SetRcvEvents(revents);
if (tmp_evts == EV_ERROR)
{
obj->HangupNotify();
continue;
}
if (tmp_evts == EV_ERROR)
{
obj->HangupNotify();
continue;
}
if (revents & KQ_EVENT_READ)
{
ret = obj->InputNotify();
if (ret != 0)
{
continue;
}
}
if (revents & KQ_EVENT_READ)
{
ret = obj->InputNotify();
if (ret != 0)
{
continue;
}
}
if (revents & KQ_EVENT_WRITE)
{
ret = obj->OutputNotify();
if (ret != 0)
{
continue;
}
}
}
if (revents & KQ_EVENT_WRITE)
{
ret = obj->OutputNotify();
if (ret != 0)
{
continue;
}
}
}
}
void KqueueProxy::KqueueDispatch()
{
int nfd;
int wait_time = KqueueGetTimeout();
if (wait_time) {
struct timespec ts;
ts.tv_sec = wait_time / 1000;
ts.tv_nsec = 0;
nfd = ff_kevent(_kqfd, NULL, 0, _evtlist, _maxfd, &ts);
} else {
nfd = ff_kevent(_kqfd, NULL, 0, _evtlist, _maxfd, NULL);
}
if (nfd <= 0)
{
return;
}
int nfd;
int wait_time = KqueueGetTimeout();
if (wait_time) {
struct timespec ts;
ts.tv_sec = wait_time / 1000;
ts.tv_nsec = 0;
nfd = ff_kevent(_kqfd, NULL, 0, _evtlist, _maxfd, &ts);
} else {
nfd = ff_kevent(_kqfd, NULL, 0, _evtlist, _maxfd, NULL);
}
if (nfd <= 0)
{
return;
}
KqueueRcvEventList(nfd);
KqueueRcvEventList(nfd);
}
int KqueuerObj::InputNotify()
{
MicroThread* thread = this->GetOwnerThread();
if (thread == NULL)
{
kqueue_assert(0);
MicroThread* thread = this->GetOwnerThread();
if (thread == NULL)
{
kqueue_assert(0);
MTLOG_ERROR("kqueue fd obj, no thread ptr, wrong");
return -1;
}
}
if (thread->HasFlag(MicroThread::IO_LIST))
{
if (thread->HasFlag(MicroThread::IO_LIST))
{
MtFrame* frame = MtFrame::Instance();
frame->RemoveIoWait(thread);
frame->InsertRunable(thread);
}
}
return 0;
return 0;
}
int KqueuerObj::OutputNotify()
@ -476,7 +476,7 @@ int KqueuerObj::OutputNotify()
return -1;
}
// 多个事件同时到达, 防重复操作
// Multiple events arrive at the same time
if (thread->HasFlag(MicroThread::IO_LIST))
{
MtFrame* frame = MtFrame::Instance();
@ -503,7 +503,7 @@ int KqueuerObj::KqueueCtlAdd(void* args)
int osfd = this->GetOsfd();
int new_events = this->GetEvents();
// 通知对象需要更新, FD通知对象理论上不会复用, 这里做冲突检查, 异常log记录
// Notify object needs updating
KqueuerObj* old_obj = fd_ref->GetNotifyObj();
if ((old_obj != NULL) && (old_obj != this))
{
@ -512,7 +512,6 @@ int KqueuerObj::KqueueCtlAdd(void* args)
}
fd_ref->SetNotifyObj(this);
// 调用框架的epoll ctl接口, 屏蔽epoll ctrl细节
if (!frame->KqueueCtrlAdd(osfd, new_events))
{
MTLOG_ERROR("kqfd ref add failed, log");
@ -532,7 +531,6 @@ int KqueuerObj::KqueueCtlDel(void* args)
int osfd = this->GetOsfd();
int events = this->GetEvents();
// 通知对象需要更新, FD通知对象理论上不会复用, 这里做冲突检查, 异常log记录
KqueuerObj* old_obj = fd_ref->GetNotifyObj();
if (old_obj != this)
{
@ -541,8 +539,7 @@ int KqueuerObj::KqueueCtlDel(void* args)
}
fd_ref->SetNotifyObj(NULL);
// 调用框架的epoll ctl接口, 屏蔽epoll ctrl细节
if (!frame->KqueueCtrlDelRef(osfd, events, false)) // 引用有风险, 弊大于利, 关闭掉
if (!frame->KqueueCtrlDelRef(osfd, events, false))
{
MTLOG_ERROR("kqfd ref del failed, log");
fd_ref->SetNotifyObj(old_obj);

View File

@ -45,10 +45,6 @@ namespace NS_MICRO_THREAD {
#define KQ_EVENT_READ 1
#define KQ_EVENT_WRITE 2
/******************************************************************************/
/* 操作系统头文件适配定义 */
/******************************************************************************/
/**
* @brief add more detail for linux <sys/queue.h>, freebsd and University of California
* @info queue.h version 8.3 (suse) diff version 8.5 (tlinux)
@ -90,119 +86,84 @@ do { \
/******************************************************************************/
/* Kqueue proxy 定义与实现部分 */
/* Kqueue proxy definition and implementation */
/******************************************************************************/
class KqueueProxy;
class MicroThread;
/**
* @brief kqueue通知对象基类定义
*/
class KqueuerObj
{
protected:
int _fd;
int _events;
int _revents;
int _type;
MicroThread* _thread;
protected:
int _fd;
int _events;
int _revents;
int _type;
MicroThread* _thread;
public:
public:
TAILQ_ENTRY(KqueuerObj) _entry;
TAILQ_ENTRY(KqueuerObj) _entry;
explicit KqueuerObj(int fd = -1) {
_fd = fd;
_events = 0;
_revents = 0;
_type = 0;
_thread = NULL;
};
virtual ~KqueuerObj(){};
explicit KqueuerObj(int fd = -1) {
_fd = fd;
_events = 0;
_revents = 0;
_type = 0;
_thread = NULL;
};
virtual ~KqueuerObj(){};
virtual int InputNotify();
virtual int OutputNotify();
virtual int HangupNotify();
virtual int KqueueCtlAdd(void* args);
virtual int KqueueCtlDel(void* args);
virtual int InputNotify();
virtual int OutputNotify();
virtual int HangupNotify();
virtual int KqueueCtlAdd(void* args);
virtual int KqueueCtlDel(void* args);
/**
* @brief fd打开可读事件侦听
*/
void EnableInput() { _events |= KQ_EVENT_READ; };
void EnableInput() { _events |= KQ_EVENT_READ; };
/**
* @brief fd打开可写事件侦听
*/
void EnableOutput() { _events |= KQ_EVENT_WRITE; };
void EnableOutput() { _events |= KQ_EVENT_WRITE; };
/**
* @brief fd关闭可读事件侦听
*/
void DisableInput() { _events &= ~KQ_EVENT_READ; };
void DisableInput() { _events &= ~KQ_EVENT_READ; };
/**
* @brief fd关闭可写事件侦听
*/
void DisableOutput() { _events &= ~KQ_EVENT_WRITE; };
void DisableOutput() { _events &= ~KQ_EVENT_WRITE; };
/**
* @brief socket设置读取封装
*/
int GetOsfd() { return _fd; };
void SetOsfd(int fd) { _fd = fd; };
int GetOsfd() { return _fd; };
void SetOsfd(int fd) { _fd = fd; };
/**
* @brief 访
*/
int GetEvents() { return _events; };
void SetRcvEvents(int revents) { _revents = revents; };
int GetRcvEvents() { return _revents; };
int GetEvents() { return _events; };
void SetRcvEvents(int revents) { _revents = revents; };
int GetRcvEvents() { return _revents; };
/**
* @brief ,
*/
int GetNtfyType() { return _type; };
virtual void Reset() {
_fd = -1;
_events = 0;
_revents = 0;
_type = 0;
_thread = NULL;
};
/**
* @brief 线
* @param thread 线
*/
void SetOwnerThread(MicroThread* thread) { _thread = thread; };
MicroThread* GetOwnerThread() { return _thread; };
int GetNtfyType() { return _type; };
virtual void Reset() {
_fd = -1;
_events = 0;
_revents = 0;
_type = 0;
_thread = NULL;
};
void SetOwnerThread(MicroThread* thread) { _thread = thread; };
MicroThread* GetOwnerThread() { return _thread; };
};
typedef TAILQ_HEAD(__KqFdList, KqueuerObj) KqObjList; ///< 高效的双链管理
typedef struct kevent KqEvent; ///< 重定义一下kqueue event
typedef TAILQ_HEAD(__KqFdList, KqueuerObj) KqObjList;
typedef struct kevent KqEvent;
/**
* @brief EPOLL支持同一FD多个线程侦听, ,
* @info , , , 20150623
*/
class KqFdRef
{
private:
int _wr_ref; ///< 监听写的引用计数
int _rd_ref; ///< 监听读的引用计数
int _events; ///< 当前正在侦听的事件列表
int _revents; ///< 当前该fd收到的事件信息, 仅在epoll_wait后处理中有效
KqueuerObj* _kqobj; ///< 单独注册调度器对象一个fd关联一个对象
int _wr_ref;
int _rd_ref;
int _events;
int _revents;
KqueuerObj* _kqobj;
public:
/**
* @brief
*/
KqFdRef() {
_wr_ref = 0;
_rd_ref = 0;
@ -212,9 +173,6 @@ public:
};
~KqFdRef(){};
/**
* @brief
*/
void SetListenEvents(int events) {
_events = events;
};
@ -222,9 +180,6 @@ public:
return _events;
};
/**
* @brief
*/
void SetNotifyObj(KqueuerObj* ntfy) {
_kqobj = ntfy;
};
@ -232,9 +187,6 @@ public:
return _kqobj;
};
/**
* @brief
*/
void AttachEvents(int event) {
if (event & KQ_EVENT_READ) {
_rd_ref++;
@ -260,9 +212,7 @@ public:
}
};
/**
* @brief
*/
int ReadRefCnt() { return _rd_ref; };
int WriteRefCnt() { return _wr_ref; };
@ -271,47 +221,47 @@ public:
class KqueueProxy
{
public:
static const int DEFAULT_MAX_FD_NUM = 100000;
public:
static const int DEFAULT_MAX_FD_NUM = 100000;
private:
int _kqfd;
int _maxfd;
KqEvent* _evtlist;
KqFdRef* _kqrefs;
private:
int _kqfd;
int _maxfd;
KqEvent* _evtlist;
KqFdRef* _kqrefs;
public:
KqueueProxy();
virtual ~KqueueProxy(){};
public:
KqueueProxy();
virtual ~KqueueProxy(){};
int InitKqueue(int max_num);
void TermKqueue(void);
int InitKqueue(int max_num);
void TermKqueue(void);
virtual int KqueueGetTimeout(void) { return 0; };
virtual bool KqueueSchedule(KqObjList* fdlist, KqueuerObj* fd, int timeout) { return false; };
bool KqueueAdd(KqObjList& fdset);
bool KqueueDel(KqObjList& fdset);
void KqueueDispatch(void);
bool KqueueAddObj(KqueuerObj* obj);
bool KqueueDelObj(KqueuerObj* obj);
bool KqueueCtrlAdd(int fd, int new_events);
bool KqueueCtrlDel(int fd, int new_events);
bool KqueueCtrlDelRef(int fd, int new_events, bool use_ref);
virtual int KqueueGetTimeout(void) { return 0; };
virtual bool KqueueSchedule(KqObjList* fdlist, KqueuerObj* fd, int timeout) { return false; };
bool KqueueAdd(KqObjList& fdset);
bool KqueueDel(KqObjList& fdset);
void KqueueDispatch(void);
bool KqueueAddObj(KqueuerObj* obj);
bool KqueueDelObj(KqueuerObj* obj);
bool KqueueCtrlAdd(int fd, int new_events);
bool KqueueCtrlDel(int fd, int new_events);
bool KqueueCtrlDelRef(int fd, int new_events, bool use_ref);
KqFdRef* KqFdRefGet(int fd) {
return ((fd >= _maxfd) || (fd < 0)) ? (KqFdRef*)NULL : &_kqrefs[fd];
}
KqFdRef* KqFdRefGet(int fd) {
return ((fd >= _maxfd) || (fd < 0)) ? (KqFdRef*)NULL : &_kqrefs[fd];
}
void KqueueNtfyReg(int fd, KqueuerObj* obj) {
KqFdRef* ref = KqFdRefGet(fd);
if (ref) {
ref->SetNotifyObj(obj);
}
};
void KqueueNtfyReg(int fd, KqueuerObj* obj) {
KqFdRef* ref = KqFdRefGet(fd);
if (ref) {
ref->SetNotifyObj(obj);
}
};
protected:
void KqueueRcvEventList(int evtfdnum);
protected:
void KqueueRcvEventList(int evtfdnum);
};
}

View File

@ -35,29 +35,12 @@ using namespace NS_MICRO_THREAD;
#define ASSERT(statement)
//#define ASSERT(statement) assert(statement)
/**
* @brief
* @param jbf jmpbuff数组指针
*/
extern "C" int save_context(jmp_buf jbf);
/**
* @brief
* @param jbf jmpbuff数组指针
* @param ret , 1
*/
extern "C" void restore_context(jmp_buf jbf, int ret);
/**
* @brief
* @param jbf jmpbuff数组指针
* @param esp
*/
extern "C" void replace_esp(jmp_buf jbf, void* esp);
/**
* @brief ,
*/
Thread::Thread(int stack_size)
{
_stack_size = stack_size ? stack_size : ThreadPool::default_stack_size;
@ -68,7 +51,7 @@ Thread::Thread(int stack_size)
/**
* @brief LINUX x86/x86_64下的栈申请,
* @brief LINUX x86/x86_64's allocated stacks.
*/
bool Thread::InitStack()
{
@ -76,7 +59,7 @@ bool Thread::InitStack()
return true;
}
///< 栈索引与栈内存分离, 防越界
///< stack index and memory are separated to prevent out of bounds.
_stack = (MtStack*)calloc(1, sizeof(MtStack));
if (NULL == _stack)
{
@ -102,8 +85,8 @@ bool Thread::InitStack()
_stack->_stk_size = _stack_size;
_stack->_stk_bottom = _stack->_vaddr + MEM_PAGE_SIZE;
_stack->_stk_top = _stack->_stk_bottom + _stack->_stk_size;
// valgrind support: register stack frame
_stack->valgrind_id = VALGRIND_STACK_REGISTER(_stack->_stk_bottom, _stack->_stk_top);
// valgrind support: register stack frame
_stack->valgrind_id = VALGRIND_STACK_REGISTER(_stack->_stk_bottom, _stack->_stk_top);
_stack->_esp = _stack->_stk_top - STACK_PAD_SIZE;
@ -114,29 +97,23 @@ bool Thread::InitStack()
}
/**
* @brief
*/
void Thread::FreeStack()
{
if (!_stack) {
return;
}
munmap(_stack->_vaddr, _stack->_vaddr_size);
// valgrind support: deregister stack frame
VALGRIND_STACK_DEREGISTER(_stack->valgrind_id);
// valgrind support: deregister stack frame
VALGRIND_STACK_DEREGISTER(_stack->valgrind_id);
free(_stack);
_stack = NULL;
}
/**
* @brief ,,
*/
void Thread::InitContext()
{
if (save_context(_jmpbuf) != 0)
{
ScheduleObj::Instance()->ScheduleStartRun(); // 直接调用 this->run?
ScheduleObj::Instance()->ScheduleStartRun();
}
if (_stack != NULL)
@ -145,9 +122,6 @@ void Thread::InitContext()
}
}
/**
* @brief , ,
*/
void Thread::SwitchContext()
{
if (save_context(_jmpbuf) == 0)
@ -156,17 +130,12 @@ void Thread::SwitchContext()
}
}
/**
* @brief , ,
*/
void Thread::RestoreContext()
{
restore_context(_jmpbuf, 1);
}
/**
* @brief 线,
*/
bool Thread::Initial()
{
if (!InitStack())
@ -180,18 +149,12 @@ bool Thread::Initial()
return true;
}
/**
* @brief 线,
*/
void Thread::Destroy()
{
FreeStack();
memset(&_jmpbuf, 0, sizeof(_jmpbuf));
}
/**
* @brief 线,
*/
void Thread::Reset()
{
_wakeup_time = 0;
@ -201,10 +164,6 @@ void Thread::Reset()
CleanState();
}
/**
* @brief 线,
* @param ms
*/
void Thread::sleep(int ms)
{
utime64_t now = ScheduleObj::Instance()->ScheduleGetTime();
@ -216,9 +175,6 @@ void Thread::sleep(int ms)
}
}
/**
* @brief , 线
*/
void Thread::Wait()
{
if (save_context(_jmpbuf) == 0)
@ -227,24 +183,17 @@ void Thread::Wait()
}
}
/**
* @brief ,,
*/
bool Thread::CheckStackHealth(char *esp)
{
if (!_stack)
return false;
if (!_stack)
return false;
if (esp > _stack->_stk_bottom && esp < _stack->_stk_top)
return true;
else
return false;
if (esp > _stack->_stk_bottom && esp < _stack->_stk_top)
return true;
else
return false;
}
/**
* @brief 线, 线
* @param type ,
*/
MicroThread::MicroThread(ThreadType type)
{
memset(&_entry, 0, sizeof(_entry));
@ -258,9 +207,6 @@ MicroThread::MicroThread(ThreadType type)
_parent = NULL;
}
/**
* @breif 线
*/
void MicroThread::CleanState()
{
TAILQ_INIT(&_fdset);
@ -273,16 +219,12 @@ void MicroThread::CleanState()
_parent = NULL;
}
/**
* @brief 线
*/
void MicroThread::Run()
{
if (_start) {
_start(_args);
}
// 二级线程, 触发父线程进入可运行态
if (this->IsSubThread()) {
this->WakeupParent();
}
@ -291,9 +233,6 @@ void MicroThread::Run()
ScheduleObj::Instance()->ScheduleThread();
}
/**
* @brief 线线
*/
void MicroThread::WakeupParent()
{
MicroThread* parent = this->GetParent();
@ -311,17 +250,11 @@ void MicroThread::WakeupParent()
}
}
/**
* @brief 线
*/
bool MicroThread::HasNoSubThread()
{
return TAILQ_EMPTY(&_sub_list);
}
/**
* @brief 线线
*/
void MicroThread::AddSubThread(MicroThread* sub)
{
ASSERT(!sub->HasFlag(MicroThread::SUB_LIST));
@ -334,9 +267,6 @@ void MicroThread::AddSubThread(MicroThread* sub)
sub->SetFlag(MicroThread::SUB_LIST);
}
/**
* @brief 线线
*/
void MicroThread::RemoveSubThread(MicroThread* sub)
{
ASSERT(sub->HasFlag(MicroThread::SUB_LIST));
@ -349,11 +279,7 @@ void MicroThread::RemoveSubThread(MicroThread* sub)
sub->UnsetFlag(MicroThread::SUB_LIST);
}
/**
* @brief 访
*/
ScheduleObj *ScheduleObj::_instance = NULL; ///< 静态句柄初始化
ScheduleObj *ScheduleObj::_instance = NULL;
inline ScheduleObj* ScheduleObj::Instance()
{
if (NULL == _instance)
@ -364,18 +290,12 @@ inline ScheduleObj* ScheduleObj::Instance()
return _instance;
}
/**
* @brief 线,
*/
void ScheduleObj::ScheduleThread()
{
MtFrame* frame = MtFrame::Instance();
frame->ThreadSchdule();
}
/**
* @brief ,
*/
utime64_t ScheduleObj::ScheduleGetTime()
{
MtFrame* frame = MtFrame::Instance();
@ -390,9 +310,6 @@ utime64_t ScheduleObj::ScheduleGetTime()
}
}
/**
* @brief 线sleep状态
*/
void ScheduleObj::ScheduleSleep()
{
MtFrame* frame = MtFrame::Instance();
@ -406,9 +323,6 @@ void ScheduleObj::ScheduleSleep()
frame->ThreadSchdule();
}
/**
* @brief 线pend状态
*/
void ScheduleObj::SchedulePend()
{
MtFrame* frame = MtFrame::Instance();
@ -422,9 +336,6 @@ void ScheduleObj::SchedulePend()
frame->ThreadSchdule();
}
/**
* @brief 线pend状态,
*/
void ScheduleObj::ScheduleUnpend(void* pthread)
{
MtFrame* frame = MtFrame::Instance();
@ -438,11 +349,6 @@ void ScheduleObj::ScheduleUnpend(void* pthread)
frame->InsertRunable(thread);
}
/**
* @brief 线,
*/
void ScheduleObj::ScheduleReclaim()
{
MtFrame* frame = MtFrame::Instance();
@ -455,9 +361,6 @@ void ScheduleObj::ScheduleReclaim()
frame->FreeThread(thread);
}
/**
* @brief
*/
void ScheduleObj::ScheduleStartRun()
{
MtFrame* frame = MtFrame::Instance();
@ -471,15 +374,9 @@ void ScheduleObj::ScheduleStartRun()
}
/**
* @brief 线
*/
unsigned int ThreadPool::default_thread_num = DEFAULT_THREAD_NUM; ///< 默认2000微线程待命
unsigned int ThreadPool::default_stack_size = DEFAULT_STACK_SIZE; ///< 默认128K栈大小
unsigned int ThreadPool::default_thread_num = DEFAULT_THREAD_NUM; ///< 2000 micro threads.
unsigned int ThreadPool::default_stack_size = DEFAULT_STACK_SIZE; ///< 128k stack.
/**
* @brief 线
*/
bool ThreadPool::InitialPool(int max_num)
{
MicroThread *thread = NULL;
@ -509,9 +406,6 @@ bool ThreadPool::InitialPool(int max_num)
}
}
/**
* @brief 线
*/
void ThreadPool::DestroyPool()
{
MicroThread* thread = NULL;
@ -527,13 +421,9 @@ void ThreadPool::DestroyPool()
_use_num = 0;
}
/**
* @brief 线
* @return 线
*/
MicroThread* ThreadPool::AllocThread()
{
MT_ATTR_API_SET(492069, _total_num); // 微线程池大小
MT_ATTR_API_SET(492069, _total_num);
MicroThread* thread = NULL;
if (!_freelist.empty())
@ -569,10 +459,6 @@ MicroThread* ThreadPool::AllocThread()
return thread;
}
/**
* @brief 线
* @param thread 线
*/
void ThreadPool::FreeThread(MicroThread* thread)
{
ASSERT(!thread->HasFlag(MicroThread::FREE_LIST));
@ -581,7 +467,6 @@ void ThreadPool::FreeThread(MicroThread* thread)
_freelist.push(thread);
thread->SetFlag(MicroThread::FREE_LIST);
///< 空闲队列 > default_thread_num, 则释放最老的, 不可以释放当前
unsigned int free_num = _freelist.size();
if ((free_num > default_thread_num) && (free_num > 1))
{
@ -595,12 +480,9 @@ void ThreadPool::FreeThread(MicroThread* thread)
int ThreadPool::GetUsedNum(void)
{
return _use_num;
return _use_num;
}
/**
* @brief 线,
*/
MtFrame *MtFrame::_instance = NULL;
inline MtFrame* MtFrame::Instance ()
{
@ -612,30 +494,20 @@ inline MtFrame* MtFrame::Instance ()
return _instance;
}
/**
* @brief HOOK系统api的设置
*/
void MtFrame::SetHookFlag() {
mt_set_hook_flag();
};
/**
* @brief ,
*/
bool MtFrame::InitFrame(LogAdapter* logadpt, int max_thread_num)
{
_log_adpt = logadpt;
// 设置最大允许的线程数目, 尝试调节epoll监控的fd数目
if ((this->InitKqueue(max_thread_num) < 0) || !this->InitialPool(max_thread_num))
{
MTLOG_ERROR("Init epoll or thread pool failed");
this->Destroy();
return false;
}
// 按需重置堆大小, 放大堆个数为2倍
if (_sleeplist.HeapResize(max_thread_num * 2) < 0)
{
MTLOG_ERROR("Init heap list failed");
@ -643,7 +515,6 @@ bool MtFrame::InitFrame(LogAdapter* logadpt, int max_thread_num)
return false;
}
// 定时器管理初始化, 放大堆个数为2倍
_timer = new CTimerMng(max_thread_num * 2);
if (NULL == _timer)
{
@ -652,7 +523,6 @@ bool MtFrame::InitFrame(LogAdapter* logadpt, int max_thread_num)
return false;
}
// 守护线程单独初始化
_daemon = AllocThread();
if (NULL == _daemon)
{
@ -664,7 +534,6 @@ bool MtFrame::InitFrame(LogAdapter* logadpt, int max_thread_num)
_daemon->SetState(MicroThread::RUNABLE);
_daemon->SetSartFunc(MtFrame::DaemonRun, this);
// 特殊线程, 无需INIT, 不初始化栈, 也无回调注册, 但需要统一调度
_primo = new MicroThread(MicroThread::PRIMORDIAL);
if (NULL == _primo)
{
@ -675,20 +544,16 @@ bool MtFrame::InitFrame(LogAdapter* logadpt, int max_thread_num)
_primo->SetState(MicroThread::RUNNING);
SetActiveThread(_primo);
// 更新最新时间戳
_last_clock = GetSystemMS();
TAILQ_INIT(&_iolist);
TAILQ_INIT(&_pend_list);
//SetHookFlag();
//SetHookFlag();
return true;
}
/**
* @brief
*/
void MtFrame::Destroy(void)
{
if (NULL == _instance )
@ -741,20 +606,11 @@ void MtFrame::Destroy(void)
_instance = NULL;
}
/**
* @brief 线
*/
char* MtFrame::Version()
{
return IMT_VERSION;
}
/**
* @brief 线
* @param entry 线
* @param args 线
* @return 线, NULL表示失败
*/
MicroThread* MtFrame::CreateThread(ThreadStart entry, void *args, bool runable)
{
MtFrame* mtframe = MtFrame::Instance();
@ -778,39 +634,32 @@ int MtFrame::Loop(void* args)
MtFrame* mtframe = MtFrame::Instance();
MicroThread* daemon = mtframe->DaemonThread();
mtframe->KqueueDispatch();
mtframe->SetLastClock(mtframe->GetSystemMS());
mtframe->WakeupTimeout();
mtframe->CheckExpired();
daemon->SwitchContext();
mtframe->KqueueDispatch();
mtframe->SetLastClock(mtframe->GetSystemMS());
mtframe->WakeupTimeout();
mtframe->CheckExpired();
daemon->SwitchContext();
return 0;
return 0;
}
/**
* @brief 线, static类型
* @param args 线
*/
void MtFrame::DaemonRun(void* args)
{
/*
/*
MtFrame* mtframe = MtFrame::Instance();
MicroThread* daemon = mtframe->DaemonThread();
while (true) {
mtframe->KqueueDispatch();
mtframe->SetLastClock(mtframe->GetSystemMS());
mtframe->WakeupTimeout();
mtframe->CheckExpired();
daemon->SwitchContext();
}
*/
ff_run(MtFrame::Loop, NULL);
while (true) {
mtframe->KqueueDispatch();
mtframe->SetLastClock(mtframe->GetSystemMS());
mtframe->WakeupTimeout();
mtframe->CheckExpired();
daemon->SwitchContext();
}
*/
ff_run(MtFrame::Loop, NULL);
}
/**
* @brief 线线
*/
MicroThread *MtFrame::GetRootThread()
{
if (NULL == _curr_thread)
@ -837,9 +686,6 @@ MicroThread *MtFrame::GetRootThread()
return parent;
}
/**
* @brief 线
*/
void MtFrame::ThreadSchdule()
{
MicroThread* thread = NULL;
@ -860,9 +706,6 @@ void MtFrame::ThreadSchdule()
thread->RestoreContext();
}
/**
* @brief
*/
void MtFrame::CheckExpired()
{
static utime64_t check_time = 0;
@ -881,9 +724,6 @@ void MtFrame::CheckExpired()
}
}
/**
* @brief , 线
*/
void MtFrame::WakeupTimeout()
{
utime64_t now = GetLastClock();
@ -891,7 +731,7 @@ void MtFrame::WakeupTimeout()
while (thread && (thread->GetWakeupTime() <= now))
{
if (thread->HasFlag(MicroThread::IO_LIST))
{
{
RemoveIoWait(thread);
}
else
@ -905,16 +745,13 @@ void MtFrame::WakeupTimeout()
}
}
/**
* @brief epoll wait前,
*/
int MtFrame::KqueueGetTimeout()
{
utime64_t now = GetLastClock();
MicroThread* thread = dynamic_cast<MicroThread*>(_sleeplist.HeapTop());
if (!thread)
{
return 10; //默认10ms epollwait
return 10; //default 10ms epollwait
}
else if (thread->GetWakeupTime() < now)
{
@ -926,10 +763,6 @@ int MtFrame::KqueueGetTimeout()
}
}
/**
* @brief 线,
* @param thread 线
*/
inline void MtFrame::InsertSleep(MicroThread* thread)
{
ASSERT(!thread->HasFlag(MicroThread::SLEEP_LIST));
@ -944,10 +777,6 @@ inline void MtFrame::InsertSleep(MicroThread* thread)
}
}
/**
* @brief 线,
* @param thread 线
*/
inline void MtFrame::RemoveSleep(MicroThread* thread)
{
ASSERT(thread->HasFlag(MicroThread::SLEEP_LIST));
@ -961,10 +790,6 @@ inline void MtFrame::RemoveSleep(MicroThread* thread)
}
}
/**
* @brief 线, IO等待状态
* @param thread 线
*/
inline void MtFrame::InsertIoWait(MicroThread* thread)
{
ASSERT(!thread->HasFlag(MicroThread::IO_LIST));
@ -973,10 +798,6 @@ inline void MtFrame::InsertIoWait(MicroThread* thread)
InsertSleep(thread);
}
/**
* @brief 线, IO等待状态
* @param thread 线
*/
void MtFrame::RemoveIoWait(MicroThread* thread)
{
ASSERT(thread->HasFlag(MicroThread::IO_LIST));
@ -986,10 +807,6 @@ void MtFrame::RemoveIoWait(MicroThread* thread)
RemoveSleep(thread);
}
/**
* @brief 线,
* @param thread 线
*/
void MtFrame::InsertRunable(MicroThread* thread)
{
ASSERT(!thread->HasFlag(MicroThread::RUN_LIST));
@ -1000,10 +817,6 @@ void MtFrame::InsertRunable(MicroThread* thread)
_waitnum++;
}
/**
* @brief 线,
* @param thread 线
*/
inline void MtFrame::RemoveRunable(MicroThread* thread)
{
ASSERT(thread->HasFlag(MicroThread::RUN_LIST));
@ -1014,11 +827,6 @@ inline void MtFrame::RemoveRunable(MicroThread* thread)
_waitnum--;
}
/**
* @brief 线, pend等待状态
* @param thread 线
*/
void MtFrame::InsertPend(MicroThread* thread)
{
ASSERT(!thread->HasFlag(MicroThread::PEND_LIST));
@ -1027,10 +835,6 @@ void MtFrame::InsertPend(MicroThread* thread)
thread->SetState(MicroThread::PENDING);
}
/**
* @brief 线, PEND等待状态
* @param thread 线
*/
void MtFrame::RemovePend(MicroThread* thread)
{
ASSERT(thread->HasFlag(MicroThread::PEND_LIST));
@ -1038,10 +842,6 @@ void MtFrame::RemovePend(MicroThread* thread)
TAILQ_REMOVE(&_pend_list, thread, _entry);
}
/**
* @brief 线, 线
* @param timeout ,
*/
void MtFrame::WaitNotify(utime64_t timeout)
{
MicroThread* thread = GetActiveThread();
@ -1051,13 +851,6 @@ void MtFrame::WaitNotify(utime64_t timeout)
thread->SwitchContext();
}
/**
* @brief 线, cpu
* @param fdlist socket列表
* @param fd fd信息
* @param timeout ,
* @return true , false
*/
bool MtFrame::KqueueSchedule(KqObjList* fdlist, KqueuerObj* fd, int timeout)
{
MicroThread* thread = GetActiveThread();
@ -1067,7 +860,6 @@ bool MtFrame::KqueueSchedule(KqObjList* fdlist, KqueuerObj* fd, int timeout)
return false;
}
// 1. 整合该线程需要关心的epoll调度对象
thread->ClearAllFd();
if (fdlist)
{
@ -1078,7 +870,6 @@ bool MtFrame::KqueueSchedule(KqObjList* fdlist, KqueuerObj* fd, int timeout)
thread->AddFd(fd);
}
// 2. 设置epoll监听事件, 调整超时时间, 切换IO等待状态, 触发切换
thread->SetWakeupTime(timeout + this->GetLastClock());
if (!this->KqueueAdd(thread->GetFdSet()))
{
@ -1088,7 +879,6 @@ bool MtFrame::KqueueSchedule(KqObjList* fdlist, KqueuerObj* fd, int timeout)
this->InsertIoWait(thread);
thread->SwitchContext();
// 3. 调度OK, 判定超时, epoll ctrl 还原状态
int rcvnum = 0;
KqObjList& rcvfds = thread->GetFdSet();
KqueuerObj* fdata = NULL;
@ -1099,9 +889,9 @@ bool MtFrame::KqueueSchedule(KqObjList* fdlist, KqueuerObj* fd, int timeout)
rcvnum++;
}
}
this->KqueueDel(rcvfds); // 在一个函数中ADD, DEL 闭环控制
this->KqueueDel(rcvfds);
if (rcvnum == 0) // 超时处理, 返回错误
if (rcvnum == 0)
{
errno = ETIME;
return false;
@ -1110,16 +900,6 @@ bool MtFrame::KqueueSchedule(KqObjList* fdlist, KqueuerObj* fd, int timeout)
return true;
}
/**
* @brief 线IO函数 recvfrom
* @param fd socket信息
* @param buf
* @param len
* @param from
* @param fromlen
* @param timeout ,
* @return >0 , <0
*/
int MtFrame::recvfrom(int fd, void *buf, int len, int flags, struct sockaddr *from, socklen_t *fromlen, int timeout)
{
MtFrame* mtframe = MtFrame::Instance();
@ -1129,9 +909,9 @@ int MtFrame::recvfrom(int fd, void *buf, int len, int flags, struct sockaddr *fr
if(fd<0 || !buf || len<1)
{
errno = EINVAL;
MTLOG_ERROR("recvfrom failed, errno: %d (%m)", errno);
return -10;
errno = EINVAL;
MTLOG_ERROR("recvfrom failed, errno: %d (%m)", errno);
return -10;
}
if (timeout <= -1)
@ -1180,16 +960,6 @@ int MtFrame::recvfrom(int fd, void *buf, int len, int flags, struct sockaddr *fr
}
/**
* @brief 线IO函数 sendto
* @param fd socket信息
* @param msg
* @param len
* @param to
* @param tolen
* @param timeout ,
* @return >0 , <0
*/
int MtFrame::sendto(int fd, const void *msg, int len, int flags, const struct sockaddr *to, int tolen, int timeout)
{
MtFrame* mtframe = MtFrame::Instance();
@ -1199,9 +969,9 @@ int MtFrame::sendto(int fd, const void *msg, int len, int flags, const struct so
if(fd<0 || !msg || len<1)
{
errno = EINVAL;
MTLOG_ERROR("sendto failed, errno: %d (%m)", errno);
return -10;
errno = EINVAL;
MTLOG_ERROR("sendto failed, errno: %d (%m)", errno);
return -10;
}
int n = 0;
@ -1236,14 +1006,6 @@ int MtFrame::sendto(int fd, const void *msg, int len, int flags, const struct so
return n;
}
/**
* @brief 线IO函数 connect
* @param fd socket信息
* @param addr server的目的地址
* @param addrlen
* @param timeout ,
* @return =0 , <0
*/
int MtFrame::connect(int fd, const struct sockaddr *addr, int addrlen, int timeout)
{
MtFrame* mtframe = MtFrame::Instance();
@ -1253,9 +1015,9 @@ int MtFrame::connect(int fd, const struct sockaddr *addr, int addrlen, int timeo
if(fd<0 || !addr || addrlen<1)
{
errno = EINVAL;
MTLOG_ERROR("connect failed, errno: %d (%m)", errno);
return -10;
errno = EINVAL;
MTLOG_ERROR("connect failed, errno: %d (%m)", errno);
return -10;
}
int n = 0;
@ -1269,7 +1031,7 @@ int MtFrame::connect(int fd, const struct sockaddr *addr, int addrlen, int timeo
return -1;
}
if (errno == EISCONN) // 已连接, 返回成功
if (errno == EISCONN)
{
return 0;
}
@ -1295,14 +1057,6 @@ int MtFrame::connect(int fd, const struct sockaddr *addr, int addrlen, int timeo
return n;
}
/**
* @brief 线IO函数 accept
* @param fd
* @param addr
* @param addrlen
* @param timeout ,
* @return >=0 accept的socket描述符, <0
*/
int MtFrame::accept(int fd, struct sockaddr *addr, socklen_t *addrlen, int timeout)
{
MtFrame* mtframe = MtFrame::Instance();
@ -1312,9 +1066,9 @@ int MtFrame::accept(int fd, struct sockaddr *addr, socklen_t *addrlen, int timeo
if(fd<0)
{
errno = EINVAL;
MTLOG_ERROR("accept failed, errno: %d (%m)", errno);
return -10;
errno = EINVAL;
MTLOG_ERROR("accept failed, errno: %d (%m)", errno);
return -10;
}
int acceptfd = 0;
@ -1349,15 +1103,6 @@ int MtFrame::accept(int fd, struct sockaddr *addr, socklen_t *addrlen, int timeo
return acceptfd;
}
/**
* @brief 线IO函数 read
* @param fd socket信息
* @param buf
* @param nbyte
* @param timeout ,
* @return >0 , <0
*/
ssize_t MtFrame::read(int fd, void *buf, size_t nbyte, int timeout)
{
MtFrame* mtframe = MtFrame::Instance();
@ -1367,9 +1112,9 @@ ssize_t MtFrame::read(int fd, void *buf, size_t nbyte, int timeout)
if(fd<0 || !buf || nbyte<1)
{
errno = EINVAL;
MTLOG_ERROR("read failed, errno: %d (%m)", errno);
return -10;
errno = EINVAL;
MTLOG_ERROR("read failed, errno: %d (%m)", errno);
return -10;
}
ssize_t n = 0;
@ -1404,14 +1149,6 @@ ssize_t MtFrame::read(int fd, void *buf, size_t nbyte, int timeout)
return n;
}
/**
* @brief 线IO函数 write
* @param fd socket信息
* @param buf
* @param nbyte
* @param timeout ,
* @return >0 , <0
*/
ssize_t MtFrame::write(int fd, const void *buf, size_t nbyte, int timeout)
{
MtFrame* mtframe = MtFrame::Instance();
@ -1421,9 +1158,9 @@ ssize_t MtFrame::write(int fd, const void *buf, size_t nbyte, int timeout)
if(fd<0 || !buf || nbyte<1)
{
errno = EINVAL;
MTLOG_ERROR("write failed, errno: %d (%m)", errno);
return -10;
errno = EINVAL;
MTLOG_ERROR("write failed, errno: %d (%m)", errno);
return -10;
}
ssize_t n = 0;
@ -1470,15 +1207,6 @@ ssize_t MtFrame::write(int fd, const void *buf, size_t nbyte, int timeout)
return nbyte;
}
/**
* @brief 线IO函数 recv
* @param fd socket信息
* @param buf
* @param len
* @param timeout ,
* @return >0 , <0
*/
int MtFrame::recv(int fd, void *buf, int len, int flags, int timeout)
{
MtFrame* mtframe = MtFrame::Instance();
@ -1488,9 +1216,9 @@ int MtFrame::recv(int fd, void *buf, int len, int flags, int timeout)
if(fd<0 || !buf || len<1)
{
errno = EINVAL;
MTLOG_ERROR("recv failed, errno: %d (%m)", errno);
return -10;
errno = EINVAL;
MTLOG_ERROR("recv failed, errno: %d (%m)", errno);
return -10;
}
if (timeout <= -1)
@ -1539,14 +1267,6 @@ int MtFrame::recv(int fd, void *buf, int len, int flags, int timeout)
}
/**
* @brief 线IO函数 send
* @param fd socket信息
* @param buf
* @param nbyte
* @param timeout ,
* @return >0 , <0
*/
ssize_t MtFrame::send(int fd, const void *buf, size_t nbyte, int flags, int timeout)
{
MtFrame* mtframe = MtFrame::Instance();
@ -1556,9 +1276,9 @@ ssize_t MtFrame::send(int fd, const void *buf, size_t nbyte, int flags, int time
if(fd<0 || !buf || nbyte<1)
{
errno = EINVAL;
MTLOG_ERROR("send failed, errno: %d (%m)", errno);
return -10;
errno = EINVAL;
MTLOG_ERROR("send failed, errno: %d (%m)", errno);
return -10;
}
ssize_t n = 0;
@ -1605,11 +1325,6 @@ ssize_t MtFrame::send(int fd, const void *buf, size_t nbyte, int flags, int time
return nbyte;
}
/**
* @brief 线sleep接口, ms
*/
void MtFrame::sleep(int ms)
{
MtFrame* frame = MtFrame::Instance();
@ -1620,13 +1335,6 @@ void MtFrame::sleep(int ms)
}
}
/**
* @brief 线IO函数 recv
* @param fd socket信息
* @param events EPOLLIN or EPOLLOUT
* @param timeout ,
* @return >0 , <0
*/
int MtFrame::WaitEvents(int fd, int events, int timeout)
{
MtFrame* mtframe = MtFrame::Instance();
@ -1669,5 +1377,3 @@ int MtFrame::WaitEvents(int fd, int events, int timeout)
return epfd.GetRcvEvents();
}
}

View File

@ -54,269 +54,159 @@ using std::queue;
namespace NS_MICRO_THREAD {
#define STACK_PAD_SIZE 128 ///< 栈上下隔离区域的大小
#define MEM_PAGE_SIZE 4096 ///< 内存页默认大小
#define DEFAULT_STACK_SIZE 128*1024 ///< 默认栈大小128K
#define DEFAULT_THREAD_NUM 2000 ///< 默认2000个初始线程
#define STACK_PAD_SIZE 128
#define MEM_PAGE_SIZE 4096
#define DEFAULT_STACK_SIZE 128*1024
#define DEFAULT_THREAD_NUM 2000
typedef unsigned long long utime64_t; ///< 64位的时间定义
typedef void (*ThreadStart)(void*); ///< 微线程入口函数定义
typedef unsigned long long utime64_t;
typedef void (*ThreadStart)(void*);
/**
* @brief 线,
*/
class ScheduleObj
{
public:
/**
* @brief 访
*/
static ScheduleObj* Instance (void);
/**
* @brief ,
*/
utime64_t ScheduleGetTime(void);
/**
* @brief 线
*/
void ScheduleThread(void);
/**
* @brief 线sleep状态
*/
void ScheduleSleep(void);
/**
* @brief 线pend状态
*/
void SchedulePend(void);
/**
* @brief 线pend状态,
*/
void ScheduleUnpend(void* thread);
/**
* @brief 线,
*/
void ScheduleReclaim(void);
/**
* @brief
*/
void ScheduleStartRun(void);
private:
static ScheduleObj* _instance; // 私有句柄
static ScheduleObj* _instance;
};
/**
* @brief 线
*/
struct MtStack
{
int _stk_size; ///< 栈的大小, 有效使用空间
int _vaddr_size; ///< 申请的buff总大小
char *_vaddr; ///< 申请的内存基地址
void *_esp; ///< 栈的esp寄存器
char *_stk_bottom; ///< 栈最低的地址空间
char *_stk_top; ///< 栈最高的地址空间
void *_private; ///< 线程私有数据
int valgrind_id; ///< valgrind id
int _stk_size;
int _vaddr_size;
char *_vaddr;
void *_esp;
char *_stk_bottom;
char *_stk_top;
void *_private;
int valgrind_id;
};
/**
* @brief 线
*/
class Thread : public HeapEntry
{
public:
/**
* @brief
*/
explicit Thread(int stack_size = 0);
virtual ~Thread(){};
/**
* @brief 线
*/
virtual void Run(void){};
/**
* @brief 线,
*/
bool Initial(void);
/**
* @brief 线,
*/
void Destroy(void);
/**
* @brief 线,
*/
void Reset(void);
/**
* @brief 线,
* @param ms
*/
void sleep(int ms);
/**
* @brief 线, 线
*/
void Wait();
/**
* @brief , ,
*/
void SwitchContext(void);
/**
* @brief ,
*/
void RestoreContext(void);
/**
* @brief
* @return 线
*/
utime64_t GetWakeupTime(void) {
return _wakeup_time;
};
/**
* @brief
* @param waketime 线
*/
void SetWakeupTime(utime64_t waketime) {
_wakeup_time = waketime;
};
/**
* @brief 线
* @param data 线使
*/
void SetPrivate(void *data)
{
_stack->_private = data;
}
/**
* @brief 线
*/
void* GetPrivate()
{
return _stack->_private;
}
/**
* @brief ,,
*/
bool CheckStackHealth(char *esp);
protected:
/**
* @brief 线,
*/
virtual void CleanState(void){};
/**
* @brief
*/
virtual bool InitStack(void);
/**
* @brief
*/
virtual void FreeStack(void);
/**
* @brief ,,
*/
virtual void InitContext(void);
private:
MtStack* _stack; ///< 私有栈指针
jmp_buf _jmpbuf; ///< 上下文jmpbuff
int _stack_size; ///< 栈大小字段
utime64_t _wakeup_time; ///< 睡眠唤醒时间
MtStack* _stack;
jmp_buf _jmpbuf;
int _stack_size;
utime64_t _wakeup_time;
};
/**
* @brief 线
*/
class MicroThread : public Thread
{
public:
enum ThreadType
{
NORMAL = 0, ///< 默认普通线程, 没有动态申请的栈信息
PRIMORDIAL = 1, ///< 原生线程, main函数开启
DAEMON = 2, ///< 守护线程, 底层IO EPOLL管理与调度触发
SUB_THREAD = 3, ///< 二级线程, 仅执行简单工作
NORMAL = 0, ///< normal thread, no dynamic allocated stack infomations.
PRIMORDIAL = 1, ///< primordial thread, created when frame initialized.
DAEMON = 2, ///< daemon thread, IO event management and scheduling trigger.
SUB_THREAD = 3, ///< sub thread, run simple task.
};
enum ThreadFlag
{
NOT_INLIST = 0x0, ///< 无队列状态
FREE_LIST = 0x1, ///< 空闲队列中
IO_LIST = 0x2, ///< IO等待队列中
SLEEP_LIST = 0x4, ///< 主动SLEEP中
RUN_LIST = 0x8, ///< 可运行队列中
PEND_LIST = 0x10, ///< 阻塞队列中
SUB_LIST = 0x20, ///< 二级线程队列中
NOT_INLIST = 0x0,
FREE_LIST = 0x1,
IO_LIST = 0x2,
SLEEP_LIST = 0x4,
RUN_LIST = 0x8,
PEND_LIST = 0x10,
SUB_LIST = 0x20,
};
enum ThreadState
{
INITIAL = 0, ///< 初始化状态
RUNABLE = 1, ///< 可运行状态
RUNNING = 2, ///< 正在运行中
SLEEPING = 3, ///< IO等待或SLEEP中
PENDING = 4, ///< 阻塞状态中, 等待子线程OK等
INITIAL = 0,
RUNABLE = 1,
RUNNING = 2,
SLEEPING = 3,
PENDING = 4,
};
typedef TAILQ_ENTRY(MicroThread) ThreadLink; ///< 微线程链接
typedef TAILQ_HEAD(__ThreadSubTailq, MicroThread) SubThreadList; ///< 微线程队列定义
typedef TAILQ_ENTRY(MicroThread) ThreadLink;
typedef TAILQ_HEAD(__ThreadSubTailq, MicroThread) SubThreadList;
public:
/**
* @brief 线
*/
MicroThread(ThreadType type = NORMAL);
~MicroThread(){};
ThreadLink _entry; ///< 状态队列入口
ThreadLink _sub_entry; ///< 子线程队列入口
ThreadLink _entry;
ThreadLink _sub_entry;
/**
* @brief 线,
* @return 线
*/
virtual utime64_t HeapValue() {
return GetWakeupTime();
};
/**
* @brief 线
*/
virtual void Run(void);
/**
* @breif fd侦听管理对列操作
*/
void ClearAllFd(void) {
TAILQ_INIT(&_fdset);
};
@ -330,9 +220,6 @@ public:
return _fdset;
};
/**
* @breif 线
*/
void SetType(ThreadType type) {
_type = type;
};
@ -340,9 +227,6 @@ public:
return _type;
};
/**
* @breif 线
*/
bool IsDaemon(void) {
return (DAEMON == _type);
};
@ -353,9 +237,6 @@ public:
return (SUB_THREAD == _type);
};
/**
* @brief 线
*/
void SetParent(MicroThread* parent) {
_parent = parent;
};
@ -364,16 +245,10 @@ public:
};
void WakeupParent();
/**
* @brief 线
*/
void AddSubThread(MicroThread* sub);
void RemoveSubThread(MicroThread* sub);
bool HasNoSubThread();
/**
* @brief 线
*/
void SetState(ThreadState state) {
_state = state;
};
@ -381,25 +256,19 @@ public:
return _state;
}
/**
* @breif 线
*/
void SetFlag(ThreadFlag flag) {
_flag = (ThreadFlag)(_flag | flag);
_flag = (ThreadFlag)(_flag | flag);
};
void UnsetFlag(ThreadFlag flag) {
_flag = (ThreadFlag)(_flag & ~flag);
};
bool HasFlag(ThreadFlag flag) {
return _flag & flag;
return _flag & flag;
};
ThreadFlag GetFlag() {
return _flag;
};
/**
* @breif 线
*/
void SetSartFunc(ThreadStart func, void* args) {
_start = func;
_args = args;
@ -411,464 +280,217 @@ public:
protected:
/**
* @breif 线
*/
virtual void CleanState(void);
private:
ThreadState _state; ///< 微线程当前状态
ThreadType _type; ///< 微线程类型
ThreadFlag _flag; ///< 微线程标记位
KqObjList _fdset; ///< 微线程关注的socket列表
SubThreadList _sub_list; ///< 二级线程的队列
MicroThread* _parent; ///< 二级线程的父线程
ThreadStart _start; ///< 微线程注册函数
void* _args; ///< 微线程注册参数
ThreadState _state;
ThreadType _type;
ThreadFlag _flag;
KqObjList _fdset;
SubThreadList _sub_list;
MicroThread* _parent;
ThreadStart _start;
void* _args;
};
typedef std::set<MicroThread*> ThreadSet; ///< 微线程set管理结构
typedef std::queue<MicroThread*> ThreadList; ///< 微线程queue管理结构
typedef std::set<MicroThread*> ThreadSet;
typedef std::queue<MicroThread*> ThreadList;
/**
* @brief 线, ,
*/
class LogAdapter
{
public:
/**
* @brief
*/
LogAdapter(){};
virtual ~LogAdapter(){};
/**
* @brief ,
* @return true , false
*/
virtual bool CheckDebug(){ return true;};
virtual bool CheckTrace(){ return true;};
virtual bool CheckError(){ return true;};
/**
* @brief
*/
virtual void LogDebug(char* fmt, ...){};
virtual void LogTrace(char* fmt, ...){};
virtual void LogError(char* fmt, ...){};
/**
* @brief
*/
virtual void AttrReportAdd(int attr, int iValue){};
virtual void AttrReportSet(int attr, int iValue){};
};
/**
* @brief 线
*/
class ThreadPool
{
public:
static unsigned int default_thread_num; ///< 默认2000微线程待命
static unsigned int default_stack_size; ///< 默认128K栈大小
static unsigned int default_thread_num;
static unsigned int default_stack_size;
/**
* @brief 线
*/
static void SetDefaultThreadNum(unsigned int num) {
default_thread_num = num;
};
/**
* @brief 线,
*/
static void SetDefaultStackSize(unsigned int size) {
default_stack_size = (size + MEM_PAGE_SIZE - 1) / MEM_PAGE_SIZE * MEM_PAGE_SIZE;
};
/**
* @brief 线
*/
bool InitialPool(int max_num);
/**
* @brief 线
*/
void DestroyPool (void);
/**
* @brief 线
* @return 线
*/
MicroThread* AllocThread(void);
/**
* @brief 线
* @param thread 线
*/
void FreeThread(MicroThread* thread);
/**
* @brief 线
* @param thread 线
*/
int GetUsedNum(void);
private:
ThreadList _freelist; ///< 空闲待命的微线程队列
int _total_num; ///< 目前总的微线程数目,后续按需控制上限
int _use_num; ///< 当前正在使用的微线程数目
int _max_num; ///< 最大并发限制数, 放置内存过度使用
ThreadList _freelist;
int _total_num;
int _use_num;
int _max_num;
};
typedef TAILQ_HEAD(__ThreadTailq, MicroThread) ThreadTailq; ///< 微线程队列定义
typedef TAILQ_HEAD(__ThreadTailq, MicroThread) ThreadTailq;
/**
* @brief 线,
*/
class MtFrame : public KqueueProxy, public ThreadPool
{
private:
static MtFrame* _instance; ///< 单例指针
LogAdapter* _log_adpt; ///< 日志接口
ThreadList _runlist; ///< 可运行queue, 无优先级
ThreadTailq _iolist; ///< 等待队列,可随机脱离队列
ThreadTailq _pend_list; ///< 等待队列,可随机脱离队列
HeapList _sleeplist; ///< 等待超时的堆, 可随机脱离, 且随时获取最小堆首
MicroThread* _daemon; ///< 守护线程, 执行epoll wait, 超时检测
MicroThread* _primo; ///< 原生线程, 使用的是原生堆栈
MicroThread* _curr_thread; ///< 当前运行线程
utime64_t _last_clock; ///< 全局时间戳, 每次idle获取一次
int _waitnum; ///< 等待运行的总线程数, 可调节调度的节奏
CTimerMng* _timer; ///< TCP保活专用的timer定时器
int _realtime; /// < 使用实时时间0, 未设置
static MtFrame* _instance;
LogAdapter* _log_adpt;
ThreadList _runlist;
ThreadTailq _iolist;
ThreadTailq _pend_list;
HeapList _sleeplist;
MicroThread* _daemon;
MicroThread* _primo;
MicroThread* _curr_thread;
utime64_t _last_clock;
int _waitnum;
CTimerMng* _timer;
int _realtime;
public:
friend class ScheduleObj; ///< 调度器对象, 是框架类的门面模式, 友元处理
friend class ScheduleObj;
public:
/**
* @brief 线,
*/
static MtFrame* Instance (void);
/**
* @brief 线IO函数 sendto
* @param fd socket信息
* @param msg
* @param len
* @param to
* @param tolen
* @param timeout ,
* @return >0 , <0
*/
static int sendto(int fd, const void *msg, int len, int flags, const struct sockaddr *to, int tolen, int timeout);
/**
* @brief 线IO函数 recvfrom
* @param fd socket信息
* @param buf
* @param len
* @param from
* @param fromlen
* @param timeout ,
* @return >0 , <0
*/
static int recvfrom(int fd, void *buf, int len, int flags, struct sockaddr *from, socklen_t *fromlen, int timeout);
/**
* @brief 线IO函数 connect
* @param fd socket信息
* @param addr server的目的地址
* @param addrlen
* @param timeout ,
* @return >0 , <0
*/
static int connect(int fd, const struct sockaddr *addr, int addrlen, int timeout);
/**
* @brief 线IO函数 accept
* @param fd
* @param addr
* @param addrlen
* @param timeout ,
* @return >=0 accept的socket描述符, <0
*/
static int accept(int fd, struct sockaddr *addr, socklen_t *addrlen, int timeout);
/**
* @brief 线IO函数 read
* @param fd socket信息
* @param buf
* @param nbyte
* @param timeout ,
* @return >0 , <0
*/
static ssize_t read(int fd, void *buf, size_t nbyte, int timeout);
/**
* @brief 线IO函数 write
* @param fd socket信息
* @param buf
* @param nbyte
* @param timeout ,
* @return >0 , <0
*/
static ssize_t write(int fd, const void *buf, size_t nbyte, int timeout);
/**
* @brief 线IO函数 recv
* @param fd socket信息
* @param buf
* @param len
* @param timeout ,
* @return >0 , <0
*/
static int recv(int fd, void *buf, int len, int flags, int timeout);
/**
* @brief 线IO函数 send
* @param fd socket信息
* @param buf
* @param nbyte
* @param timeout ,
* @return >0 , <0
*/
static ssize_t send(int fd, const void *buf, size_t nbyte, int flags, int timeout);
/**
* @brief 线sleep接口, ms
*/
static void sleep(int ms);
/**
* @brief 线,
* @param fd socket信息
* @param events EPOLLIN or EPOLLOUT
* @param timeout ,
* @return >0 , <0
*/
static int WaitEvents(int fd, int events, int timeout);
/**
* @brief 线
* @param entry 线
* @param args 线
* @return 线, NULL表示失败
*/
static MicroThread* CreateThread(ThreadStart entry, void *args, bool runable = true);
/**
* @brief 线, static类型
* @param args 线
*/
static void DaemonRun(void* args);
static int Loop(void* args);
static int Loop(void* args);
/**
* @brief 线线
*/
MicroThread *GetRootThread();
/**
* @brief ,
*/
bool InitFrame(LogAdapter* logadpt = NULL, int max_thread_num = 50000);
/**
* @brief HOOK系统api的设置
*/
void SetHookFlag();
/**
* @brief
*/
void Destroy (void);
/**
* @brief 线
*/
char* Version(void);
/**
* @brief
*/
utime64_t GetLastClock(void) {
if(_realtime)
{
return GetSystemMS();
}
if(_realtime)
{
return GetSystemMS();
}
return _last_clock;
};
/**
* @brief 线
*/
MicroThread* GetActiveThread(void) {
return _curr_thread;
};
/**
* @brief 线, ,
* @return 线
*/
int RunWaitNum(void) {
return _waitnum;
};
/**
* @brief 访
*/
LogAdapter* GetLogAdpt(void) {
return _log_adpt;
};
/**
* @brief
*/
CTimerMng* GetTimerMng(void) {
return _timer;
};
/**
* @brief epoll wait前,
*/
virtual int KqueueGetTimeout(void);
/**
* @brief 线, cpu,
* @param fdlist socket列表
* @param fd fd信息
* @param timeout ,
* @return true , false
*/
virtual bool KqueueSchedule(KqObjList* fdlist, KqueuerObj* fd, int timeout);
/**
* @brief 线, 线
* @param timeout ,
*/
void WaitNotify(utime64_t timeout);
/**
* @brief 线, IO等待状态,
* @param thread 线
*/
void RemoveIoWait(MicroThread* thread);
/**
* @brief 线, ,
* @param thread 线
*/
void InsertRunable(MicroThread* thread);
/**
* @brief 线, pend等待状态
* @param thread 线
*/
void InsertPend(MicroThread* thread);
/**
* @brief 线, PEND等待状态
* @param thread 线
*/
void RemovePend(MicroThread* thread);
void SetRealTime(int realtime_)
{
_realtime =realtime_;
}
void SetRealTime(int realtime_)
{
_realtime =realtime_;
}
private:
/**
* @brief 线
*/
MtFrame():_realtime(1){ _curr_thread = NULL; };
/**
* @brief 线线
*/
MicroThread* DaemonThread(void){
return _daemon;
};
};
/**
* @brief 线
*/
void ThreadSchdule(void);
/**
* @brief
*/
void CheckExpired();
/**
* @brief , 线
*/
void WakeupTimeout(void);
/**
* @brief
*/
void SetLastClock(utime64_t clock) {
_last_clock = clock;
};
/**
* @brief 线
*/
void SetActiveThread(MicroThread* thread) {
_curr_thread = thread;
};
};
/**
* @brief ,
*/
utime64_t GetSystemMS(void) {
struct timeval tv;
gettimeofday(&tv, NULL);
return (tv.tv_sec * 1000ULL + tv.tv_usec / 1000ULL);
};
/**
* @brief 线, IO等待状态
* @param thread 线
*/
void InsertSleep(MicroThread* thread);
/**
* @brief 线, IO等待状态
* @param thread 线
*/
void RemoveSleep(MicroThread* thread);
/**
* @brief 线, IO等待状态
* @param thread 线
*/
void InsertIoWait(MicroThread* thread);
/**
* @brief 线,
* @param thread 线
*/
void RemoveRunable(MicroThread* thread);
};
/**
* @brief
*/
#define MTLOG_DEBUG(fmt, args...) \
do { \
register NS_MICRO_THREAD::MtFrame *fm = NS_MICRO_THREAD::MtFrame::Instance(); \
@ -909,13 +531,13 @@ do { \
} while (0)
#define MT_ATTR_API_SET(ATTR, VALUE) \
do { \
register NS_MICRO_THREAD::MtFrame *fm = NS_MICRO_THREAD::MtFrame::Instance(); \
if (fm && fm->GetLogAdpt()) \
{ \
fm->GetLogAdpt()->AttrReportSet(ATTR, VALUE); \
} \
} while (0)
do { \
register NS_MICRO_THREAD::MtFrame *fm = NS_MICRO_THREAD::MtFrame::Instance(); \
if (fm && fm->GetLogAdpt()) \
{ \
fm->GetLogAdpt()->AttrReportSet(ATTR, VALUE); \
} \
} while (0)

View File

@ -17,12 +17,6 @@
*/
/**
* @file mt_action.cpp
* @info 线ACTION基类实现
* @time 20130924
**/
#include "micro_thread.h"
#include "mt_notify.h"
#include "mt_connection.h"
@ -32,10 +26,6 @@
using namespace std;
using namespace NS_MICRO_THREAD;
/**
* @brief item状态
*/
void IMtAction::Init()
{
_flag = MULTI_FLAG_UNDEF;
@ -50,12 +40,8 @@ void IMtAction::Init()
memset(&_addr, 0, sizeof(_addr));
}
/**
* @brief , item状态
*/
void IMtAction::Reset()
{
// 长连接, 处理成功才复用, 否则强制关闭
bool force_free = false;
if (_errno != ERR_NONE) {
force_free = true;
@ -67,9 +53,6 @@ void IMtAction::Reset()
}
}
/**
* @brief , ,
*/
KqueuerObj* IMtAction::GetNtfyObj() {
IMtConnection* conn = GetIConnection();
if (conn) {
@ -79,10 +62,6 @@ KqueuerObj* IMtAction::GetNtfyObj() {
}
};
/**
* @brief
*/
int IMtAction::InitConnEnv()
{
MtFrame* mtframe = MtFrame::Instance();
@ -96,23 +75,22 @@ int IMtAction::InitConnEnv()
return -100;
}
// 1. 分类获取conn句柄
CONN_OBJ_TYPE conn_obj_type = OBJ_CONN_UNDEF;
NTFY_OBJ_TYPE ntfy_obj_type = NTFY_OBJ_UNDEF;
MULTI_PROTO proto = this->GetProtoType();
MULTI_CONNECT type = this->GetConnType();
if ((MT_UDP == proto) && (CONN_TYPE_SESSION == type)) // UDP session模式
if ((MT_UDP == proto) && (CONN_TYPE_SESSION == type)) // UDP session
{
conn_obj_type = OBJ_UDP_SESSION;
ntfy_obj_type = NTFY_OBJ_SESSION;
}
else if (MT_UDP == proto) // UDP 其它模式
else if (MT_UDP == proto) // UDP
{
conn_obj_type = OBJ_SHORT_CONN;
ntfy_obj_type = NTFY_OBJ_THREAD;
}
else // TCP 模式
else // TCP
{
conn_obj_type = OBJ_TCP_KEEP;
ntfy_obj_type = NTFY_OBJ_THREAD;
@ -125,7 +103,6 @@ int IMtAction::InitConnEnv()
}
_conn->SetIMtActon(this);
// 2. 获取msg buff句柄
int max_len = this->GetMsgBuffSize();
MtMsgBuf* msg_buff = msgmgr->GetMsgBuf(max_len);
if (!msg_buff) {
@ -135,7 +112,6 @@ int IMtAction::InitConnEnv()
msg_buff->SetBuffType(BUFF_SEND);
_conn->SetMtMsgBuff(msg_buff);
// 3. 获取 ntfy 对象句柄
KqueuerObj* ntfy_obj = ntfymgr->GetNtfyObj(ntfy_obj_type, _ntfy_name);
if (!ntfy_obj) {
MTLOG_ERROR("Maybe no memory, ntfy type: %d, get failed", ntfy_obj_type);
@ -143,7 +119,6 @@ int IMtAction::InitConnEnv()
}
_conn->SetNtfyObj(ntfy_obj);
// 4. SESSION模型, 建立session
MicroThread* thread = mtframe->GetActiveThread();
ntfy_obj->SetOwnerThread(thread);
this->SetIMsgPtr((IMtMsg*)thread->GetThreadArgs());
@ -158,10 +133,6 @@ int IMtAction::InitConnEnv()
return 0;
}
/**
* @brief ,
*/
int IMtAction::DoEncode()
{
MtMsgBuf* msg_buff = NULL;
@ -185,9 +156,6 @@ int IMtAction::DoEncode()
return 0;
}
/**
* @brief ,
*/
int IMtAction::DoInput()
{
MtMsgBuf* msg_buff = NULL;
@ -210,7 +178,6 @@ int IMtAction::DoInput()
return ret;
}
int IMtAction::DoProcess()
{
MtMsgBuf* msg_buff = NULL;
@ -238,15 +205,11 @@ int IMtAction::DoError()
return this->HandleError((int)_errno, _msg);
}
/**
* @brief
*/
IMtAction::IMtAction()
{
Init();
}
IMtAction::~IMtAction()
{
Reset();

View File

@ -16,12 +16,6 @@
* and limitations under the License.
*/
/**
* @file mt_action.h
* @info 线ACTION基类定义
**/
#ifndef __MT_ACTION_H__
#define __MT_ACTION_H__
@ -34,244 +28,136 @@
namespace NS_MICRO_THREAD {
/**
* @brief
*/
enum MULTI_STATE
{
MULTI_FLAG_UNDEF = 0x0, ///< 初始化, 未启动
MULTI_FLAG_INIT = 0x1, ///< socket创建已成功
MULTI_FLAG_OPEN = 0x2, ///< socket连接已打开
MULTI_FLAG_SEND = 0x4, ///< 请求报文已经发送
MULTI_FLAG_FIN = 0x8, ///< 应答报文已经接收到
MULTI_FLAG_UNDEF = 0x0,
MULTI_FLAG_INIT = 0x1,
MULTI_FLAG_OPEN = 0x2,
MULTI_FLAG_SEND = 0x4,
MULTI_FLAG_FIN = 0x8,
};
/**
* @brief
*/
enum MULTI_CONNECT
{
CONN_UNKNOWN = 0,
CONN_TYPE_SHORT = 0x1, ///< 短连接, 一次交互后关闭
CONN_TYPE_LONG = 0x2, ///< 长连接,每次使用后, 可回收重复使用
CONN_TYPE_SESSION = 0x4, ///< 长连接按session id 复用, 防串包
CONN_TYPE_SHORT = 0x1,
CONN_TYPE_LONG = 0x2,
CONN_TYPE_SESSION = 0x4,
};
/**
* @brief
*/
enum MULTI_ERROR
{
ERR_NONE = 0,
ERR_SOCKET_FAIL = -1, ///< 创建sock失败
ERR_CONNECT_FAIL = -2, ///< 连接失败
ERR_SEND_FAIL = -3, ///< 发送报文失败
ERR_RECV_FAIL = -4, ///< 接收失败
ERR_RECV_TIMEOUT = -5, ///< 接收超时
ERR_KQUEUE_FAIL = -6, ///< epoll失败
ERR_FRAME_ERROR = -7, ///< 框架失败
ERR_PEER_CLOSE = -8, ///< 对方关闭
ERR_PARAM_ERROR = -9, ///< 参数错误
ERR_MEMORY_ERROR = -10, ///< 内存申请失败
ERR_ENCODE_ERROR = -11, ///< 封包失败
ERR_DST_ADDR_ERROR = -12, ///< 目标地址获取失败
ERR_SOCKET_FAIL = -1,
ERR_CONNECT_FAIL = -2,
ERR_SEND_FAIL = -3,
ERR_RECV_FAIL = -4,
ERR_RECV_TIMEOUT = -5,
ERR_KQUEUE_FAIL = -6,
ERR_FRAME_ERROR = -7,
ERR_PEER_CLOSE = -8,
ERR_PARAM_ERROR = -9,
ERR_MEMORY_ERROR = -10,
ERR_ENCODE_ERROR = -11,
ERR_DST_ADDR_ERROR = -12,
};
/**
* @brief 线
*/
class IMtAction : public ISession
{
public:
/**
* @brief 线
*/
IMtAction();
virtual ~IMtAction();
/**
* @brief (, 使inline)
* @param dst -
*/
void SetMsgDstAddr(struct sockaddr_in* dst) {
void SetMsgDstAddr(struct sockaddr_in* dst) {
memcpy(&_addr, dst, sizeof(_addr));
};
/**
* @brief
* @return
*/
struct sockaddr_in* GetMsgDstAddr() {
return &_addr;
};
};
struct sockaddr_in* GetMsgDstAddr() {
return &_addr;
};
/**
* @brief buff大小, 使msgbuff队列
* @return 0
*/
void SetMsgBuffSize(int buff_size) {
_buff_size = buff_size;
};
/**
* @brief buff大小
* @return buff最大长度
*/
int GetMsgBuffSize() {
return (_buff_size > 0) ? _buff_size : 65535;
}
}
/**
* @brief session的名字id
* @return 0
*/
void SetSessionName(int name) {
_ntfy_name = name;
};
/**
* @brief session的名字id
* @return session
*/
int GetSessionName() {
return _ntfy_name;
}
}
/**
* @brief proto信息
*/
void SetProtoType(MULTI_PROTO proto) {
_proto = proto;
};
/**
* @brief proto信息
* @return proto type
*/
MULTI_PROTO GetProtoType() {
return _proto;
};
/**
* @brief
*/
void SetConnType(MULTI_CONNECT type) {
_conn_type = type;
};
/**
* @brief
* @return conn type
*/
MULTI_CONNECT GetConnType() {
return _conn_type;
};
/**
* @brief errno
*/
void SetErrno(MULTI_ERROR err) {
_errno = err;
};
/**
* @brief ERRNO信息
* @return ERRONO
*/
MULTI_ERROR GetErrno() {
return _errno;
};
/**
* @brief timecost
*/
void SetCost(int cost) {
_time_cost = cost;
};
/**
* @brief timecost信息
* @return timecost
*/
int GetCost() {
return _time_cost;
};
/**
* @brief
* @param flag -
*/
void SetMsgFlag(MULTI_STATE flag) {
void SetMsgFlag(MULTI_STATE flag) {
_flag = flag;
};
/**
* @brief
* @return flag -
*/
};
MULTI_STATE GetMsgFlag() {
return _flag;
};
/**
* @brief
* @return IMtConn指针
*/
void SetIMsgPtr(IMtMsg* msg ) {
_msg = msg;
};
/**
* @brief
* @return IMtConn指针
*/
IMtMsg* GetIMsgPtr() {
return _msg;
};
/**
* @brief
* @return IMtConn指针
*/
void SetIConnection(IMtConnection* conn) {
_conn = conn;
};
/**
* @brief
* @return IMtConn指针
*/
IMtConnection* GetIConnection() {
return _conn;
};
/**
* @brief
*/
void Init();
/**
* @brief , Action状态
*/
void Reset();
/**
* @brief , ,
*/
KqueuerObj* GetNtfyObj();
/**
* @brief , ,
*/
int InitConnEnv();
/**
* @brief ,
*/
int DoEncode();
int DoInput();
int DoProcess();
@ -279,46 +165,28 @@ public:
public:
/**
* @brief
* @return >0 -, < 0
*/
virtual int HandleEncode(void* buf, int& len, IMtMsg* msg){return 0;};
/**
* @brief CHECK接口, TCP的分包接口
* @return > 0 ,, =0 , <0 (-65535 UDP串包)
*/
virtual int HandleInput(void* buf, int len, IMtMsg* msg){return 0;};
/**
* @brief ,
* @return 0 ,
*/
virtual int HandleProcess(void* buf, int len, IMtMsg* msg){return 0;};
/**
* @brief , MULTI_ERROR
* @info handleprocess失败,
* @return 0 ,
*/
virtual int HandleError(int err, IMtMsg* msg){return 0;};
protected:
MULTI_STATE _flag; // 处理结束标记信息, 当前状态信息
MULTI_PROTO _proto; // 协议类型 UDP/TCP
MULTI_CONNECT _conn_type; // 连接类型 长短连接
MULTI_ERROR _errno; // 错误码信息, 0成功其他错误
struct sockaddr_in _addr; // 请求时填写指定发送的stAddr
int _time_cost; // 本次请求应答耗时, 毫秒
int _buff_size; // 本次请求最大请求与应答长度
int _ntfy_name; // 关联的session ntfy的名字, session模型适用
IMtMsg* _msg; // 消息指针, 上级指针
IMtConnection* _conn; // 连接器指针, 下级指针, 管理生存期
MULTI_STATE _flag;
MULTI_PROTO _proto;
MULTI_CONNECT _conn_type;
MULTI_ERROR _errno;
struct sockaddr_in _addr;
int _time_cost;
int _buff_size;
int _ntfy_name;
IMtMsg* _msg;
IMtConnection* _conn;
};
}

File diff suppressed because it is too large Load Diff

View File

@ -19,7 +19,6 @@
/**
* @filename mt_api.h
* @info 线api, 线API
*/
#ifndef __MT_API_H__
@ -32,377 +31,109 @@ using std::vector;
namespace NS_MICRO_THREAD {
/******************************************************************************/
/* 微线程用户接口定义: UDP短连接收发接口 */
/******************************************************************************/
/**
* @brief socket收发接口, socket来决定上下文,
* [] UDP发送buff, static变量, []
* @param dst -
* @param pkg -
* @param len -
* @param rcv_buf -buff
* @param buf_size -modify-buff大小, ,
* @param timeout -, ms
* @return 0 , -1 socket失败, -2 , -3 , errno
*/
int mt_udpsendrcv(struct sockaddr_in* dst, void* pkg, int len, void* rcv_buf, int& buf_size, int timeout);
/******************************************************************************/
/* 微线程用户接口定义: TCP连接池收发接口 */
/******************************************************************************/
/**
* @brief TCP检测报文是否接收完整的回调函数定义
* @param buf
* @param len
* @return >0 ; 0 ; <0
*/
typedef int (*MtFuncTcpMsgLen)(void* buf, int len);
/**
* @brief TCP会采用连接池的方式复用IP/PORT连接, 10
* [] tcp接收发送buff, static变量, []
* @param dst -
* @param pkg -
* @param len -
* @param rcv_buf -buff
* @param buf_size -modify-buff大小, ,
* @param timeout -, ms
* @param check_func -
* @return 0 , -1 socket失败, -2 , -3 ,
* -4 , -5 , -6 , -7 -10
*/
int mt_tcpsendrcv(struct sockaddr_in* dst, void* pkg, int len, void* rcv_buf, int& buf_size,
int timeout, MtFuncTcpMsgLen chek_func);
enum MT_TCP_CONN_TYPE
{
MT_TCP_SHORT = 1, /// 短连接
MT_TCP_LONG = 2, /// 长连接
MT_TCP_SHORT_SNDONLY = 3, /// 短连接只发
MT_TCP_LONG_SNDONLY = 4, /// 长连接只发
MT_TCP_SHORT = 1,
MT_TCP_LONG = 2,
MT_TCP_SHORT_SNDONLY = 3,
MT_TCP_LONG_SNDONLY = 4,
MT_TCP_BUTT
};
/**
* @brief TCP收发接口
* [] tcp接收发送buff, static变量, []
* @param dst -
* @param pkg -
* @param len -
* @param rcv_buf -buffNULL
* @param buf_size -modify-buff大小, , NULL
* @param timeout -, ms
* @param check_func -
* @param type -
* MT_TCP_SHORT:
* MT_TCP_LONG :
* MT_TCP_LONG_SNDONLY :
* MT_TCP_SHORT_SNDONLY:
* @return 0 , -1 socket失败, -2 , -3 ,
* -4 , -5 , -6 , -7 , -10
*/
int mt_tcpsendrcv_ex(struct sockaddr_in* dst, void* pkg, int len, void* rcv_buf, int* buf_size,
int timeout, MtFuncTcpMsgLen func, MT_TCP_CONN_TYPE type = MT_TCP_LONG);
/**
* @brief TCP检测报文是否接收完整的回调函数
* @param buf
* @param len
* @param closed
* @param msg_ctx
* mt_tcpsendrcv中传入该参数
* mt_tcpsendrcv返回后使
* buf指针可能变化使
* @param msg_len_detected truefalsefalse
* true>0MtFuncTcpMsgChecker函数MtFuncTcpMsgChecker函数检查一次报文
* @return >0 ; 0 ; <0
*
* 0:
* 1,
* 2buf的建议长度buf长度realloc buf
*
* 0buf收满realloc bufbuf大小扩大一倍
* 0
*/
typedef int (*MtFuncTcpMsgChecker)(void* buf, int len, bool closed, void* msg_ctx, bool &msg_len_detected);
/**
* @brief TCP收发接口
* [] tcp接收发送buff, static变量, []
* @param dst -
* @param pkg -
* @param len -
* @param rcv_buf - keep_rcv_bufmalloc该内存void* rcv_buf=NULL:
* @param recv_pkg_size -buff的初始大小0
* @param timeout -, ms
* @param check_func -
* @param msg_ctx -
*
* @param type -
* MT_TCP_SHORT:
* MT_TCP_LONG :
* MT_TCP_LONG_SNDONLY :
* MT_TCP_SHORT_SNDONLY:
* @param keep_rcv_buf -true,rcv_buf赋值给传出参数bufbuf
* msg_ctx中保留相关信息malloc申请内存 bufctx保存信息
* @return 0 , -1 socket失败, -2 , -3 ,
* -4 , -5 , -6 , -7 , -10 , -11,buf失败
*/
int mt_tcpsendrcv_ex(struct sockaddr_in* dst, void* pkg, int len, void*& rcv_buf, int& recv_pkg_size,
int timeout, MtFuncTcpMsgChecker check_func, void* msg_ctx=NULL,
MT_TCP_CONN_TYPE type = MT_TCP_LONG, bool keep_rcv_buf=false);
/**
* @brief TCP会采用连接池的方式复用IP/PORT连接, 10
* [] tcp接收发送buff, static变量, []
* @param dst -
* @param pkg -
* @param len -
* @param rcv_buf - keep_rcv_buf
* @param recv_pkg_size -buff的初始大小0
* @param timeout -, ms
* @param check_func -
* @param msg_ctx -
* @param keep_rcv_buf -true,rcv_buf赋值给传出参数bufbuf
* msg_ctx中保留相关信息malloc申请内存
* @return 0 , -1 socket失败, -2 , -3 ,
* -4 , -5 , -6 , -7 , -10
*/
int mt_tcpsendrcv(struct sockaddr_in* dst, void* pkg, int len, void*& rcv_buf, int& recv_pkg_size,
int timeout, MtFuncTcpMsgChecker check_func, void* msg_ctx=NULL, bool keep_rcv_buf=false);
/******************************************************************************/
/* 微线程用户接口定义: 微线程Task多路并发模型接口定义 */
/******************************************************************************/
/**
* @brief 线
*/
class IMtTask
{
public:
/**
* @brief 线
* @return 0 -, < 0
*/
virtual int Process() { return -1; };
/**
* @brief task执行结果
* @info Process返回值
*/
void SetResult(int rc)
{
_result = rc;
}
/**
* @brief task执行结果
* @info Process返回值
*/
int GetResult(void)
{
return _result;
}
/**
* @brief task类型
*/
void SetTaskType(int type)
{
_type = type;
}
/**
* @brief task类型
* @info task使task类型
* @return task类型
*/
int GetTaskType(void)
{
return _type;
}
/**
* @brief 线
*/
IMtTask() {};
virtual ~IMtTask() {};
protected:
int _type; // task类型多种类型task业务可以自定义类型方便从基类转换
int _result; // task执行结果即Process返回值
int _type;
int _result;
};
typedef vector<IMtTask*> IMtTaskList;
/**
* @brief IO并发, Task-fork-wait模式接口
* @param req_list -task list api的task列表
* @return 0 , -1 线
*/
int mt_exec_all_task(IMtTaskList& req_list);
/******************************************************************************/
/* 微线程用户接口定义: 微线程封装系统接口 */
/******************************************************************************/
/**
* @brief 线sleep接口, ms
* @info CPU时使用
*/
void mt_sleep(int ms);
/**
* @brief 线ms
*/
unsigned long long mt_time_ms(void);
/******************************************************************************/
/* 微线程用户接口定义: 微线程用户私有数据接口 */
/******************************************************************************/
/**
* @brief IMtMsg的私有变量
* @info
*/
void mt_set_msg_private(void *data);
/**
* @brief IMtMsg的私有变量
* @return
*/
void* mt_get_msg_private();
/******************************************************************************/
/* 微线程用户接口定义: 微线程封装系统接口(不推荐使用) */
/******************************************************************************/
/**
* @brief 线
* @info 使spp线
* 使sppSyncFrame的框架初始化函数即可
* @return false: true:
*/
bool mt_init_frame(int argc=0, char * const argv[]=NULL);
/**
* @brief 线
* @info 128K
*/
void mt_set_stack_size(unsigned int bytes);
/**
* @brief 线IO函数 recvfrom
* @param fd socket信息
* @param buf
* @param len
* @param from
* @param fromlen
* @param timeout ,
* @return >0 , <0
*/
int mt_recvfrom(int fd, void *buf, int len, int flags, struct sockaddr *from, socklen_t *fromlen, int timeout);
/**
* @brief 线IO函数 sendto
* @param fd socket信息
* @param msg
* @param len
* @param to
* @param tolen
* @param timeout ,
* @return >0 , <0
*/
int mt_sendto(int fd, const void *msg, int len, int flags, const struct sockaddr *to, int tolen, int timeout);
/**
* @brief 线IO函数 connect
* @param fd socket信息
* @param addr server的目的地址
* @param addrlen
* @param timeout ,
* @return >0 , <0
*/
int mt_connect(int fd, const struct sockaddr *addr, int addrlen, int timeout);
/**
* @brief 线IO函数 accept
* @param fd
* @param addr
* @param addrlen
* @param timeout ,
* @return >=0 accept的socket描述符, <0
*/
int mt_accept(int fd, struct sockaddr *addr, socklen_t *addrlen, int timeout);
/**
* @brief 线IO函数 read
* @param fd socket信息
* @param buf
* @param nbyte
* @param timeout ,
* @return >0 , <0
*/
ssize_t mt_read(int fd, void *buf, size_t nbyte, int timeout);
/**
* @brief 线IO函数 write
* @param fd socket信息
* @param buf
* @param nbyte
* @param timeout ,
* @return >0 , <0
*/
ssize_t mt_write(int fd, const void *buf, size_t nbyte, int timeout);
/**
* @brief 线IO函数 recv
* @param fd socket信息
* @param buf
* @param len
* @param timeout ,
* @return >0 , <0
*/
ssize_t mt_recv(int fd, void *buf, int len, int flags, int timeout);
/**
* @brief 线IO函数 send
* @param fd socket信息
* @param buf
* @param nbyte
* @param timeout ,
* @return >0 , <0
*/
ssize_t mt_send(int fd, const void *buf, size_t nbyte, int flags, int timeout);
/**
* @brief 线epoll事件的包裹函数
* @param fd socket信息
* @param events IN/OUT
* @param timeout ,
* @return >0 , <0
*/
int mt_wait_events(int fd, int events, int timeout);
void* mt_start_thread(void* entry, void* args);
}
#endif

View File

@ -19,7 +19,6 @@
/**
* @filename mt_cache.cpp
* @info TCP接入buffer管理实现
*/
#include <stdlib.h>
@ -37,12 +36,6 @@
namespace NS_MICRO_THREAD {
/**
* @brief Buffer创建操作
* @param size buff大小
* @return NULL block块,
*/
TSkBuffer* new_sk_buffer(uint32_t size)
{
uint32_t total = sizeof(TSkBuffer) + size;
@ -65,11 +58,6 @@ TSkBuffer* new_sk_buffer(uint32_t size)
return block;
}
/**
* @brief Buffer释放操作
* @param block -buff块
*/
void delete_sk_buffer(TSkBuffer* block)
{
if (NULL == block) {
@ -79,13 +67,6 @@ void delete_sk_buffer(TSkBuffer* block)
free(block);
}
/**
* @brief (buff,)
* @param buff -buff指针
* @param size -
* @return buff信息
*/
TSkBuffer* reserve_sk_buffer(TSkBuffer* buff, uint32_t size)
{
if (NULL == buff) {
@ -107,13 +88,6 @@ TSkBuffer* reserve_sk_buffer(TSkBuffer* buff, uint32_t size)
return new_buff;
}
/**
* @brief cache
* @param mng -
* @param expired -,
* @param size -
*/
void sk_buffer_mng_init(TSkBuffMng* mng, uint32_t expired, uint32_t size)
{
TAILQ_INIT(&mng->free_list);
@ -122,10 +96,6 @@ void sk_buffer_mng_init(TSkBuffMng* mng, uint32_t expired, uint32_t size)
mng->size = size;
}
/**
* @brief cache
* @param mng -
*/
void sk_buffer_mng_destroy(TSkBuffMng * mng)
{
TSkBuffer* item = NULL;
@ -138,12 +108,6 @@ void sk_buffer_mng_destroy(TSkBuffMng * mng)
mng->count = 0;
}
/**
* @brief buff
* @param mng -
* @return NULL为成功获取的buff块指针
*/
TSkBuffer* alloc_sk_buffer(TSkBuffMng* mng)
{
if (NULL == mng) {
@ -167,12 +131,6 @@ TSkBuffer* alloc_sk_buffer(TSkBuffMng* mng)
return item;
}
/**
* @brief buff块
* @param mng -
* @param buff -buff指针
*/
void free_sk_buffer(TSkBuffMng* mng, TSkBuffer* buff)
{
if ((NULL == mng) || (NULL == buff)) {
@ -187,12 +145,6 @@ void free_sk_buffer(TSkBuffMng* mng, TSkBuffer* buff)
buff->data_len = 0;
}
/**
* @brief buff块
* @param mng -
* @param now -,
*/
void recycle_sk_buffer(TSkBuffMng* mng, uint32_t now)
{
TSkBuffer* item = NULL;
@ -210,12 +162,6 @@ void recycle_sk_buffer(TSkBuffMng* mng, uint32_t now)
}
}
/**
* @brief Cache管理链初始化
* @param cache -
* @param pool -buff池指针
*/
void rw_cache_init(TRWCache* cache, TSkBuffMng* pool)
{
TAILQ_INIT(&cache->list);
@ -224,10 +170,6 @@ void rw_cache_init(TRWCache* cache, TSkBuffMng* pool)
cache->pool = pool;
}
/**
* @brief Cache管理链销毁
* @param cache -
*/
void rw_cache_destroy(TRWCache* cache)
{
if ((cache == NULL) || (cache->pool == NULL)) {
@ -246,14 +188,6 @@ void rw_cache_destroy(TRWCache* cache)
cache->pool = NULL;
}
/**
* @brief Cache删除并拷贝指定长度数据
* @param cache -
* @param buff -buff的指针
* @param len -
* @return
*/
uint32_t cache_copy_out(TRWCache* cache, void* buff, uint32_t len)
{
if ((cache == NULL) || (cache->pool == NULL)) {
@ -266,7 +200,6 @@ uint32_t cache_copy_out(TRWCache* cache, void* buff, uint32_t len)
TSkBuffer* tmp = NULL;
TAILQ_FOREACH_SAFE(item, &cache->list, entry, tmp)
{
// 1. 确认拷贝数据大小
skip_len = (item->data_len > left) ? left : item->data_len;
if (out_buff != NULL)
{
@ -282,21 +215,18 @@ uint32_t cache_copy_out(TRWCache* cache, void* buff, uint32_t len)
break;
}
// 2. 移除一个block
if (cache->count > 0) {
cache->count--;
}
TAILQ_REMOVE(&cache->list, item, entry);
free_sk_buffer(cache->pool, item);
// 3. 循环变量控制
if (left == 0)
{
break;
}
}
// 整体考虑数据长度问题, 是否有足够的数据移除
skip_len = len - left;
if (cache->len > skip_len)
{
@ -310,22 +240,11 @@ uint32_t cache_copy_out(TRWCache* cache, void* buff, uint32_t len)
return skip_len;
}
/**
* @brief Cache删除掉指定长度数据
* @param cache -
* @param len -
*/
void cache_skip_data(TRWCache* cache, uint32_t len)
{
cache_copy_out(cache, NULL, len);
}
/**
* @brief Cache追加指定长度数据
* @param cache -
* @param buff -
*/
void cache_append_buffer(TRWCache* cache, TSkBuffer* buff)
{
if ((NULL == cache) || (NULL == buff))
@ -338,10 +257,6 @@ void cache_append_buffer(TRWCache* cache, TSkBuffer* buff)
cache->count++;
}
/**
* @brief Cache移除第一块内存, free
* @param cache -
*/
TSkBuffer* cache_skip_first_buffer(TRWCache* cache)
{
TSkBuffer* buff = TAILQ_FIRST(&cache->list);
@ -364,13 +279,6 @@ TSkBuffer* cache_skip_first_buffer(TRWCache* cache)
return buff;
}
/**
* @brief Cache追加指定长度数据
* @param cache -
* @param data -
* @param len -
*/
int32_t cache_append_data(TRWCache* cache, const void* data, uint32_t len)
{
if ((NULL == data) || (NULL == cache) || (NULL == cache->pool))
@ -386,7 +294,6 @@ int32_t cache_append_data(TRWCache* cache, const void* data, uint32_t len)
uint32_t left = len;
uint32_t remain = 0;
// 1. 尾空间先进行append, 因为需要回滚, 前一部分先不拷贝
TSkBuffer* tail = TAILQ_LAST(&cache->list, __sk_buff_list);
if (tail != NULL)
{
@ -403,8 +310,7 @@ int32_t cache_append_data(TRWCache* cache, const void* data, uint32_t len)
return (int32_t)len;
}
}
// 2. 有剩余buff待处理, 先申请剩余的buff, 在修改尾节点
TRWCache keep_list;
rw_cache_init(&keep_list, cache->pool);
left -= remain;
@ -429,8 +335,7 @@ int32_t cache_append_data(TRWCache* cache, const void* data, uint32_t len)
item->data_len = item->size;
left -= item->size;
}
// 3. 尝试拷贝最初的buff, 这里不会回滚了
if ((tail != NULL) && (remain > 0))
{
memcpy(tail->data + tail->data_len, data, remain);
@ -444,14 +349,6 @@ int32_t cache_append_data(TRWCache* cache, const void* data, uint32_t len)
return (int32_t)len;
}
/**
* @brief Cache整合的UDP收报接口, , 32使
* @param cache -
* @param fd - fd句柄
* @param remote_addr -ip地址
* @return
*/
int32_t cache_udp_recv(TRWCache* cache, uint32_t fd, struct sockaddr_in* remote_addr)
{
if (NULL == cache)
@ -494,13 +391,6 @@ int32_t cache_udp_recv(TRWCache* cache, uint32_t fd, struct sockaddr_in* remote_
return total;
}
/**
* @brief Cache整合的TCP收报接口
* @param cache -
* @param fd - fd句柄
* @return
*/
int32_t cache_tcp_recv(TRWCache* cache, uint32_t fd)
{
if (NULL == cache)
@ -511,7 +401,6 @@ int32_t cache_tcp_recv(TRWCache* cache, uint32_t fd)
int32_t total = 0;
for (uint32_t i = 0; i < 100; i++)
{
// 1. 每次检查尾空间, 空间满或初始状态, 申请新空间
TSkBuffer* item = TAILQ_LAST(&cache->list, __sk_buff_list);
if ((NULL == item)
|| ((item->data_len + item->data) >= item->end))
@ -524,7 +413,6 @@ int32_t cache_tcp_recv(TRWCache* cache, uint32_t fd)
cache_append_buffer(cache, item);
}
// 2. 单次最多接收size大小, 默认64K
uint8_t* buff = item->data + item->data_len;
uint32_t remain = item->end - item->data - item->data_len;
mt_hook_syscall(recv);
@ -551,7 +439,7 @@ int32_t cache_tcp_recv(TRWCache* cache, uint32_t fd)
item->data_len += recvd_len;
cache->len += recvd_len;
total += recvd_len;
if (recvd_len < (int32_t)remain) // 收不满, 可认为本次OK
if (recvd_len < (int32_t)remain)
{
return total;
}
@ -561,12 +449,6 @@ int32_t cache_tcp_recv(TRWCache* cache, uint32_t fd)
return total;
}
/**
* @brief Cache整合的TCP发送接口
* @param cache -
* @param fd - fd句柄
* @return
*/
int32_t cache_tcp_send(TRWCache* cache, uint32_t fd)
{
if ((NULL == cache) || (NULL == cache->pool))
@ -578,8 +460,7 @@ int32_t cache_tcp_send(TRWCache* cache, uint32_t fd)
{
return 0;
}
int32_t ret = 0, total = 0;
TSkBuffer* item = NULL;
TSkBuffer* tmp = NULL;
@ -612,15 +493,6 @@ int32_t cache_tcp_send(TRWCache* cache, uint32_t fd)
return total;
}
/**
* @brief Cache整合的TCP发送接口, 使IOVEC
* @param cache -
* @param fd - fd句柄
* @param data -cache后, buff
* @param len -buff长度
* @return
*/
int32_t cache_tcp_send_buff(TRWCache* cache, uint32_t fd, const void* data, uint32_t len)
{
if ((NULL == cache) || (NULL == data))
@ -628,7 +500,6 @@ int32_t cache_tcp_send_buff(TRWCache* cache, uint32_t fd, const void* data, uint
return -1;
}
// 1. 优先发送CACHE数据
int32_t ret = cache_tcp_send(cache, fd);
if (ret < 0)
{
@ -636,7 +507,6 @@ int32_t cache_tcp_send_buff(TRWCache* cache, uint32_t fd, const void* data, uint
return ret;
}
// 2. CACHE已经无数据
int32_t send_len = 0;
if (cache->len == 0)
{
@ -666,12 +536,6 @@ int32_t cache_tcp_send_buff(TRWCache* cache, uint32_t fd, const void* data, uint
return send_len;
}
/**
* @brief cache有效数据总长度
* @param multi -
* @return
*/
uint32_t get_data_len(TBuffVecPtr multi)
{
TRWCache* cache = (TRWCache*)multi;
@ -682,11 +546,6 @@ uint32_t get_data_len(TBuffVecPtr multi)
}
}
/**
* @brief cache有效数据块个数
* @param multi -
* @return
*/
uint32_t get_block_count(TBuffVecPtr multi)
{
TRWCache* cache = (TRWCache*)multi;
@ -697,11 +556,6 @@ uint32_t get_block_count(TBuffVecPtr multi)
}
}
/**
* @brief cache的第一块数据指针
* @param multi -
* @return
*/
TBuffBlockPtr get_first_block(TBuffVecPtr multi)
{
TRWCache* cache = (TRWCache*)multi;
@ -712,12 +566,6 @@ TBuffBlockPtr get_first_block(TBuffVecPtr multi)
}
}
/**
* @brief cache的下一块数据指针
* @param multi -
* @param block -
* @return
*/
TBuffBlockPtr get_next_block(TBuffVecPtr multi, TBuffBlockPtr block)
{
TRWCache* cache = (TRWCache*)multi;
@ -731,12 +579,6 @@ TBuffBlockPtr get_next_block(TBuffVecPtr multi, TBuffBlockPtr block)
}
/**
* @brief
* @param block -
* @param data --modify参数
* @param len - modify参数
*/
void get_block_data(TBuffBlockPtr block, const void** data, int32_t* len)
{
TSkBuffer* item = (TSkBuffer*)block;
@ -756,14 +598,6 @@ void get_block_data(TBuffBlockPtr block, const void** data, int32_t* len)
}
}
/**
* @brief
* @param multi -
* @param data -
* @param len -
* @return
*/
uint32_t read_cache_data(TBuffVecPtr multi, void* data, uint32_t len)
{
TRWCache* cache = (TRWCache*)multi;
@ -803,15 +637,6 @@ uint32_t read_cache_data(TBuffVecPtr multi, void* data, uint32_t len)
return offset;
}
/**
* @brief
* @param multi -
* @param data -
* @param len -
* @return
*/
uint32_t read_cache_begin(TBuffVecPtr multi, uint32_t begin, void* data, uint32_t len)
{
TRWCache* cache = (TRWCache*)multi;
@ -829,7 +654,6 @@ uint32_t read_cache_begin(TBuffVecPtr multi, uint32_t begin, void* data, uint32_
TSkBuffer* item = NULL;
TAILQ_FOREACH(item, &cache->list, entry)
{
// 1. 开始位置有剩余, 则跳过该部分
uint8_t* start_ptr = item->data;
uint32_t real_left = item->data_len;
if (pos_left > 0)
@ -840,13 +664,11 @@ uint32_t read_cache_begin(TBuffVecPtr multi, uint32_t begin, void* data, uint32_
start_ptr += skip_len;
}
// 2. 跳过后无长度剩余, 则等待下一块
if (real_left == 0)
{
continue;
}
// 3. 有剩余, 尽力拷贝最大长度
uint32_t copy_len = copy_left > real_left ? real_left : copy_left;
if (data != NULL)
{
@ -863,7 +685,4 @@ uint32_t read_cache_begin(TBuffVecPtr multi, uint32_t begin, void* data, uint32_
return offset;
}
};

View File

@ -19,7 +19,6 @@
/**
* @filename mt_cache.h
* @info TCP接入buffer管理定义
*/
#ifndef ___MT_BUFFER_CACHE_H
@ -31,268 +30,99 @@
namespace NS_MICRO_THREAD {
// 默认的buff大小
#define SK_DFLT_BUFF_SIZE 64*1024
#define SK_DFLT_ALIGN_SIZE 8
#define SK_ERR_NEED_CLOSE 10000
/**
* @brief buffer
*/
typedef struct _sk_buffer_tag
{
TAILQ_ENTRY(_sk_buffer_tag) entry; // list entry buffer LRU等
uint32_t last_time; // 上次使用时间戳
uint32_t size; // buffer节点的空间大小
uint8_t* head; // buff数据区头指针
uint8_t* end; // buff数据区结束指针
uint8_t* data; // 有效数据的头指针
uint32_t data_len; // 有效的数据长度
uint8_t buff[0]; // 原始指针区域
TAILQ_ENTRY(_sk_buffer_tag) entry;
uint32_t last_time;
uint32_t size;
uint8_t* head;
uint8_t* end;
uint8_t* data;
uint32_t data_len;
uint8_t buff[0];
} TSkBuffer;
typedef TAILQ_HEAD(__sk_buff_list, _sk_buffer_tag) TSkBuffList; // multi 事务命令队列
typedef TAILQ_HEAD(__sk_buff_list, _sk_buffer_tag) TSkBuffList;
/**
* @brief buff块
* @param size
* @return NULL为成功返回的buff指针
*/
TSkBuffer* new_sk_buffer(uint32_t size = SK_DFLT_BUFF_SIZE);
/**
* @brief buff块
* @param buff指针
*/
void delete_sk_buffer(TSkBuffer* buff);
/**
* @brief (buff,)
* @param buff -buff指针
* @param size -
* @return buff信息
*/
TSkBuffer* reserve_sk_buffer(TSkBuffer* buff, uint32_t size);
/**
* @brief buffer cache
*/
typedef struct _sk_buff_mng_tag
{
TSkBuffList free_list; // buff链表
uint32_t expired; // 超时时间
uint32_t size; // buff大小
uint32_t count; // 块个数
TSkBuffList free_list;
uint32_t expired;
uint32_t size;
uint32_t count;
} TSkBuffMng;
/**
* @brief cache
* @param mng -
* @param expired -,
* @param size -
*/
void sk_buffer_mng_init(TSkBuffMng* mng, uint32_t expired, uint32_t size = SK_DFLT_BUFF_SIZE);
/**
* @brief cache
* @param mng -
*/
void sk_buffer_mng_destroy(TSkBuffMng * mng);
/**
* @brief buff
* @param mng -
* @return NULL为成功获取的buff块指针
*/
TSkBuffer* alloc_sk_buffer(TSkBuffMng* mng);
/**
* @brief buff块
* @param mng -
* @param buff -buff指针
*/
void free_sk_buffer(TSkBuffMng* mng, TSkBuffer* buff);
/**
* @brief buff块
* @param mng -
* @param now -,
*/
void recycle_sk_buffer(TSkBuffMng* mng, uint32_t now);
/**
* @brief buffer cache
*/
typedef struct _sk_rw_cache_tag
{
TSkBuffList list; // buff链表
uint32_t len; // 数据长度
uint32_t count; // 块个数
TSkBuffMng *pool; // 全局buff池指针
TSkBuffList list;
uint32_t len;
uint32_t count;
TSkBuffMng *pool;
} TRWCache;
/**
* @brief Cache管理链初始化
* @param cache -
* @param pool -buff池指针
*/
void rw_cache_init(TRWCache* cache, TSkBuffMng* pool);
/**
* @brief Cache管理链销毁
* @param cache -
*/
void rw_cache_destroy(TRWCache* cache);
/**
* @brief Cache删除掉指定长度数据
* @param cache -
* @param len -
*/
void cache_skip_data(TRWCache* cache, uint32_t len);
/**
* @brief Cache移除第一块内存
* @param cache -
*/
TSkBuffer* cache_skip_first_buffer(TRWCache* cache);
/**
* @brief Cache追加指定长度数据
* @param cache -
* @param data -
* @param len -
*/
int32_t cache_append_data(TRWCache* cache, const void* data, uint32_t len);
/**
* @brief Cache追加指定长度数据
* @param cache -
* @param buff -
*/
void cache_append_buffer(TRWCache* cache, TSkBuffer* buff);
/**
* @brief Cache删除并拷贝指定长度数据
* @param cache -
* @param buff -buff的指针
* @param len -
* @return
*/
uint32_t cache_copy_out(TRWCache* cache, void* buff, uint32_t len);
/**
* @brief Cache整合的UDP收报接口, , 32使
* @param cache -
* @param fd - fd句柄
* @param remote_addr -ip地址
* @return
*/
int32_t cache_udp_recv(TRWCache* cache, uint32_t fd, struct sockaddr_in* remote_addr);
/**
* @brief Cache整合的TCP收报接口
* @param cache -
* @param fd - fd句柄
* @return
*/
int32_t cache_tcp_recv(TRWCache* cache, uint32_t fd);
/**
* @brief Cache整合的TCP发送接口
* @param cache -
* @param fd - fd句柄
* @return
*/
int32_t cache_tcp_send(TRWCache* cache, uint32_t fd);
/**
* @brief Cache整合的TCP发送接口, 使IOVEC
* @param cache -
* @param fd - fd句柄
* @param data -cache后, buff
* @param len -buff长度
* @return
*/
int32_t cache_tcp_send_buff(TRWCache* cache, uint32_t fd, const void* data, uint32_t len);
// interface
typedef void* TBuffVecPtr; ///< 多个block的cache管理指针句柄
typedef void* TBuffBlockPtr; ///< 单个管理块指针句柄
typedef void* TBuffVecPtr;
typedef void* TBuffBlockPtr;
/**
* @brief cache有效数据总长度
* @param multi -
* @return
*/
uint32_t get_data_len(TBuffVecPtr multi);
/**
* @brief cache有效数据块个数
* @param multi -
* @return
*/
uint32_t get_block_count(TBuffVecPtr multi);
/**
* @brief cache的第一块数据指针
* @param multi -
* @return
*/
TBuffBlockPtr get_first_block(TBuffVecPtr multi);
/**
* @brief cache的下一块数据指针
* @param multi -
* @param block -
* @return
*/
TBuffBlockPtr get_next_block(TBuffVecPtr multi, TBuffBlockPtr block);
/**
* @brief
* @param block -
* @param data --modify参数
* @param len - modify参数
*/
void get_block_data(TBuffBlockPtr block, const void** data, int32_t* len);
/**
* @brief
* @param multi -
* @param data -
* @param len -
* @return
*/
uint32_t read_cache_data(TBuffVecPtr multi, void* data, uint32_t len);
/**
* @brief
* @param multi -
* @param data -
* @param len -
* @return
*/
uint32_t read_cache_begin(TBuffVecPtr multi, uint32_t begin, void* data, uint32_t len);
};
#endif

View File

@ -19,7 +19,6 @@
/**
* @file mt_concurrent.c
* @info
* @time 20130924
**/
@ -32,14 +31,6 @@
using namespace std;
using namespace NS_MICRO_THREAD;
/**
* @brief IO的处理优化,
* @param req_list -
* @param how - EPOLLIN EPOLLOUT
* @param timeout -
* @return 0 , <0 -3
*/
int NS_MICRO_THREAD::mt_multi_netfd_poll(IMtActList& req_list, int how, int timeout)
{
KqObjList fdlist;
@ -99,11 +90,6 @@ int NS_MICRO_THREAD::mt_multi_netfd_poll(IMtActList& req_list, int how, int time
return 0;
}
/**
* @brief ITEM建立上下文的socket
* @param req_list -
* @return 0 , <0
*/
int NS_MICRO_THREAD::mt_multi_newsock(IMtActList& req_list)
{
int sock = -1, has_ok = 0;
@ -161,13 +147,6 @@ int NS_MICRO_THREAD::mt_multi_newsock(IMtActList& req_list)
}
}
/**
* @brief IO的处理,
* @param req_list -
* @param timeout -
* @return 0 , <0
*/
int NS_MICRO_THREAD::mt_multi_open(IMtActList& req_list, int timeout)
{
utime64_t start_ms = MtFrame::Instance()->GetLastClock();
@ -244,13 +223,6 @@ int NS_MICRO_THREAD::mt_multi_open(IMtActList& req_list, int timeout)
}
/**
* @brief IO的处理,
* @param req_list -
* @param timeout -
* @return 0 , <0
*/
int NS_MICRO_THREAD::mt_multi_sendto(IMtActList& req_list, int timeout)
{
utime64_t start_ms = MtFrame::Instance()->GetLastClock();
@ -284,7 +256,6 @@ int NS_MICRO_THREAD::mt_multi_sendto(IMtActList& req_list, int timeout)
return -2;
}
// 0 -还要继续发送; -1 停止发送; > 0 发送OK
ret = net_handler->SendData();
if (ret == -1)
{
@ -335,11 +306,6 @@ int NS_MICRO_THREAD::mt_multi_sendto(IMtActList& req_list, int timeout)
return 0;
}
/**
* @brief IO并发接收处理
*/
int NS_MICRO_THREAD::mt_multi_recvfrom(IMtActList& req_list, int timeout)
{
utime64_t start_ms = MtFrame::Instance()->GetLastClock();
@ -360,7 +326,7 @@ int NS_MICRO_THREAD::mt_multi_recvfrom(IMtActList& req_list, int timeout)
continue;
}
if (MULTI_FLAG_FIN == action->GetMsgFlag()) ///< 已处理完毕
if (MULTI_FLAG_FIN == action->GetMsgFlag())
{
continue;
}
@ -373,7 +339,6 @@ int NS_MICRO_THREAD::mt_multi_recvfrom(IMtActList& req_list, int timeout)
return -2;
}
// <0 失败, 0 继续收, >0 成功
ret = net_handler->RecvData();
if (ret < 0)
{
@ -415,18 +380,15 @@ int NS_MICRO_THREAD::mt_multi_recvfrom(IMtActList& req_list, int timeout)
}
}
/**
* @brief IO并发接收处理
*/
int NS_MICRO_THREAD::mt_multi_sendrcv_ex(IMtActList& req_list, int timeout)
{
utime64_t start_ms = MtFrame::Instance()->GetLastClock();
utime64_t curr_ms = 0;
int rc = mt_multi_newsock(req_list); // TODO, 可提取connect超时时间等
int rc = mt_multi_newsock(req_list);
if (rc < 0)
{
MT_ATTR_API(320842, 1); // socket失败
MT_ATTR_API(320842, 1);
MTLOG_ERROR("mt_multi_sendrcv new sock failed, ret: %d", rc);
return -1;
}
@ -434,7 +396,7 @@ int NS_MICRO_THREAD::mt_multi_sendrcv_ex(IMtActList& req_list, int timeout)
rc = mt_multi_open(req_list, timeout);
if (rc < 0)
{
MT_ATTR_API(320843, 1); // connect失败
MT_ATTR_API(320843, 1);
MTLOG_ERROR("mt_multi_sendrcv open failed, ret: %d", rc);
return -2;
}
@ -443,7 +405,7 @@ int NS_MICRO_THREAD::mt_multi_sendrcv_ex(IMtActList& req_list, int timeout)
rc = mt_multi_sendto(req_list, timeout - (curr_ms - start_ms));
if (rc < 0)
{
MT_ATTR_API(320844, 1); // 发送失败
MT_ATTR_API(320844, 1);
MTLOG_ERROR("mt_multi_sendrcv send failed, ret: %d", rc);
return -3;
}
@ -452,7 +414,7 @@ int NS_MICRO_THREAD::mt_multi_sendrcv_ex(IMtActList& req_list, int timeout)
rc = mt_multi_recvfrom(req_list, timeout - (curr_ms - start_ms));
if (rc < 0)
{
MT_ATTR_API(320845, 1); // 接收未完全成功
MT_ATTR_API(320845, 1);
MTLOG_ERROR("mt_multi_sendrcv recv failed, ret: %d", rc);
return -4;
}
@ -460,18 +422,10 @@ int NS_MICRO_THREAD::mt_multi_sendrcv_ex(IMtActList& req_list, int timeout)
return 0;
}
/**
* @brief IO并发接收处理接口, ACTON接口模型, msg
* @param req_list -action list
* @param timeout -, ms
* @return 0 , -1 ,
*/
int NS_MICRO_THREAD::mt_msg_sendrcv(IMtActList& req_list, int timeout)
{
int iRet = 0;
// 第一步, 初始化action环境, 封装请求报文
for (IMtActList::iterator it = req_list.begin(); it != req_list.end(); ++it)
{
IMtAction* pAction = *it;
@ -491,10 +445,8 @@ int NS_MICRO_THREAD::mt_msg_sendrcv(IMtActList& req_list, int timeout)
}
// 第二步, 同步收发消息, 失败也需要通知处理
mt_multi_sendrcv_ex(req_list, timeout);
// 第三步, 同步通知解包处理
for (IMtActList::iterator it = req_list.begin(); it != req_list.end(); ++it)
{
IMtAction* pAction = *it;
@ -514,7 +466,6 @@ int NS_MICRO_THREAD::mt_msg_sendrcv(IMtActList& req_list, int timeout)
}
}
// 第四步, 清理框架内部资源, 兼容各类用法
for (IMtActList::iterator it = req_list.begin(); it != req_list.end(); ++it)
{
IMtAction* pAction = *it;
@ -523,6 +474,3 @@ int NS_MICRO_THREAD::mt_msg_sendrcv(IMtActList& req_list, int timeout)
return 0;
}

View File

@ -19,7 +19,6 @@
/**
* @file mt_concurrent.h
* @info 线
* @time 20130515
**/
@ -36,62 +35,19 @@ using std::vector;
class IMtAction;
typedef vector<IMtAction*> IMtActList;
/******************************************************************************/
/* 微线程用户接口定义: 微线程Action多路并发模型接口定义 */
/******************************************************************************/
/**
* @brief IO并发接收处理接口, ACTON接口模型, msg
* @param req_list -action list
* @param timeout -, ms
* @return 0 , -1 socket失败, -2 , -100 , errno
*/
int mt_msg_sendrcv(IMtActList& req_list, int timeout);
/******************************************************************************/
/* 内部实现定义部分 */
/******************************************************************************/
/**
* @brief IO的处理优化,
* @param req_list -
* @param how - EPOLLIN EPOLLOUT
* @param timeout -
* @return 0 , <0 -3
*/
int mt_multi_netfd_poll(IMtActList& req_list, int how, int timeout);
/**
* @brief ITEM建立上下文的socket
* @param req_list -
* @return 0 , <0
*/
int mt_multi_newsock(IMtActList& req_list);
/**
* @brief IO的处理,
* @param req_list -
* @param timeout -
* @return 0 , <0
*/
int mt_multi_open(IMtActList& req_list, int timeout);
/**
* @brief IO的处理,
* @param req_list -
* @param timeout -
* @return 0 , <0
*/
int mt_multi_sendto(IMtActList& req_list, int timeout);
/**
* @brief IO并发接收处理
*/
int mt_multi_recvfrom(IMtActList& req_list, int timeout);
/**
* @brief IO并发接收处理
*/
int mt_multi_sendrcv_ex(IMtActList& req_list, int timeout);
}

View File

@ -19,7 +19,6 @@
/**
* @file mt_connection.cpp
* @info 线
* @time 20130924
**/
#include <fcntl.h>
@ -38,10 +37,6 @@
using namespace std;
using namespace NS_MICRO_THREAD;
/**
* @brief 线
*/
IMtConnection::IMtConnection()
{
_type = OBJ_CONN_UNDEF;
@ -62,10 +57,6 @@ IMtConnection::~IMtConnection()
}
}
/**
* @brief
*/
void IMtConnection::Reset()
{
if (_ntfy_obj) {
@ -83,22 +74,15 @@ void IMtConnection::Reset()
_msg_buff = NULL;
}
/**
* @brief socket建立,
* @return >0 -, fd, < 0
*/
int UdpShortConn::CreateSocket()
{
// 1. UDP短连接, 每次新创SOCKET
_osfd = socket(AF_INET, SOCK_DGRAM, 0);
if (_osfd < 0)
{
MTLOG_ERROR("socket create failed, errno %d(%s)", errno, strerror(errno));
return -1;
}
// 2. 非阻塞设置
int flags = 1;
if (ioctl(_osfd, FIONBIO, &flags) < 0)
{
@ -108,7 +92,6 @@ int UdpShortConn::CreateSocket()
return -2;
}
// 3. 更新管理信息
if (_ntfy_obj) {
_ntfy_obj->SetOsfd(_osfd);
}
@ -116,9 +99,6 @@ int UdpShortConn::CreateSocket()
return _osfd;
}
/**
* @brief socket,
*/
int UdpShortConn::CloseSocket()
{
if (_osfd < 0)
@ -132,11 +112,6 @@ int UdpShortConn::CloseSocket()
return 0;
}
/**
* @brief ,
* @return 0 , . <0 . >0
*/
int UdpShortConn::SendData()
{
if (!_action || !_msg_buff) {
@ -167,11 +142,6 @@ int UdpShortConn::SendData()
}
}
/**
* @brief ,
* @param buff
* @return -1 . -2 . >0
*/
int UdpShortConn::RecvData()
{
if (!_action || !_msg_buff) {
@ -194,19 +164,18 @@ int UdpShortConn::RecvData()
{
MTLOG_ERROR("socket recv failed, fd %d, errno %d(%s)", _osfd,
errno, strerror(errno));
return -2; // 系统错误
return -2;
}
}
else if (ret == 0)
{
return -1; // 对端关闭
return -1;
}
else
{
_msg_buff->SetHaveRcvLen(ret);
}
// 上下文检查, >0 收包完整; =0 继续等待; <0(-65535串包)其它异常
ret = _action->DoInput();
if (ret > 0)
{
@ -228,20 +197,12 @@ int UdpShortConn::RecvData()
}
}
/**
* @brief
*/
void UdpShortConn::Reset()
{
CloseSocket();
this->IMtConnection::Reset();
}
/**
* @brief , TCP的connect等
* @return 0 -, < 0
*/
int TcpKeepConn::OpenCnnect()
{
if (!_action || !_msg_buff) {
@ -279,12 +240,9 @@ int TcpKeepConn::OpenCnnect()
}
}
/**
* @brief sock的TCP复用连接
*/
int TcpKeepConn::CreateSocket()
{
if (_osfd > 0) // 复用连接时, 可跳过创建处理; 不能跳过设置ntfyfd
if (_osfd > 0)
{
if (_ntfy_obj) {
_ntfy_obj->SetOsfd(_osfd);
@ -293,15 +251,13 @@ int TcpKeepConn::CreateSocket()
return _osfd;
}
// 第一次进入时, 创建socket
_osfd = socket(AF_INET, SOCK_STREAM, 0);
if (_osfd < 0)
{
MTLOG_ERROR("create tcp socket failed, error: %d", errno);
return -1;
}
// 非阻塞设置
int flags = 1;
if (ioctl(_osfd, FIONBIO, &flags) < 0)
{
@ -311,7 +267,6 @@ int TcpKeepConn::CreateSocket()
return -2;
}
// 更新管理信息
_keep_ntfy.SetOsfd(_osfd);
_keep_ntfy.DisableOutput();
_keep_ntfy.EnableInput();
@ -323,13 +278,6 @@ int TcpKeepConn::CreateSocket()
return _osfd;
}
/**
* @brief ,
* @param dst
* @param buff
* @param size
* @return 0 , . <0 . >0
*/
int TcpKeepConn::SendData()
{
if (!_action || !_msg_buff) {
@ -360,7 +308,6 @@ int TcpKeepConn::SendData()
_msg_buff->SetHaveSndLen(have_send_len);
}
// 全部发送完毕, 返回成功, 否则继续等待
if (have_send_len >= msg_len)
{
return msg_len;
@ -371,11 +318,6 @@ int TcpKeepConn::SendData()
}
}
/**
* @brief ,
* @param buff
* @return -1 . -2 . >0
*/
int TcpKeepConn::RecvData()
{
if (!_action || !_msg_buff) {
@ -397,14 +339,14 @@ int TcpKeepConn::RecvData()
else
{
MTLOG_ERROR("recv tcp socket failed, error: %d", errno);
return -2; // 系统错误
return -2;
}
}
else if (ret == 0)
{
MTLOG_ERROR("tcp remote close, address: %s[%d]",
inet_ntoa(_dst_addr.sin_addr), ntohs(_dst_addr.sin_port));
return -1; // 对端关闭
return -1;
}
else
{
@ -412,7 +354,6 @@ int TcpKeepConn::RecvData()
_msg_buff->SetHaveRcvLen(have_rcv_len);
}
// 上下文检查, >0 收包完整; =0 继续等待; <0(-65535串包)其它异常
ret = _action->DoInput();
if (ret > 0)
{
@ -429,9 +370,6 @@ int TcpKeepConn::RecvData()
}
}
/**
* @brief socket,
*/
int TcpKeepConn::CloseSocket()
{
if (_osfd < 0)
@ -446,9 +384,6 @@ int TcpKeepConn::CloseSocket()
return 0;
}
/**
* @brief
*/
void TcpKeepConn::Reset()
{
memset(&_dst_addr, 0 ,sizeof(_dst_addr));
@ -456,17 +391,11 @@ void TcpKeepConn::Reset()
this->IMtConnection::Reset();
}
/**
* @brief
*/
void TcpKeepConn::ConnReuseClean()
{
this->IMtConnection::Reset();
}
/**
* @brief Idle缓存处理, epoll
*/
bool TcpKeepConn::IdleAttach()
{
if (_osfd < 0) {
@ -482,7 +411,6 @@ bool TcpKeepConn::IdleAttach()
_keep_ntfy.DisableOutput();
_keep_ntfy.EnableInput();
// 保活定时器添加
CTimerMng* timer = MtFrame::Instance()->GetTimerMng();
if ((NULL == timer) || !timer->start_timer(this, _keep_time))
{
@ -502,9 +430,6 @@ bool TcpKeepConn::IdleAttach()
}
}
/**
* @brief Idle取消缓存处理, 线
*/
bool TcpKeepConn::IdleDetach()
{
if (_osfd < 0) {
@ -520,7 +445,6 @@ bool TcpKeepConn::IdleDetach()
_keep_ntfy.DisableOutput();
_keep_ntfy.EnableInput();
// 保活定时器删除
CTimerMng* timer = MtFrame::Instance()->GetTimerMng();
if (NULL != timer)
{
@ -539,19 +463,12 @@ bool TcpKeepConn::IdleDetach()
}
}
/**
* @brief ,
*/
void TcpKeepConn::timer_notify()
{
MTLOG_DEBUG("keep timeout[%u], fd %d, close connection", _keep_time, _osfd);
ConnectionMgr::Instance()->CloseIdleTcpKeep(this);
}
/**
* @brief
*/
TcpKeepMgr::TcpKeepMgr()
{
_keep_hash = new HashList(10000);
@ -574,10 +491,6 @@ TcpKeepMgr::~TcpKeepMgr()
_keep_hash = NULL;
}
/**
* @brief IP地址获取TCP的保持连接
*/
TcpKeepConn* TcpKeepMgr::GetTcpKeepConn(struct sockaddr_in* dst)
{
TcpKeepConn* conn = NULL;
@ -606,9 +519,6 @@ TcpKeepConn* TcpKeepMgr::GetTcpKeepConn(struct sockaddr_in* dst)
return conn;
}
/**
* @brief IP地址缓存TCP的保持连接
*/
bool TcpKeepMgr::RemoveTcpKeepConn(TcpKeepConn* conn)
{
struct sockaddr_in* dst = conn->GetDestAddr();
@ -633,10 +543,6 @@ bool TcpKeepMgr::RemoveTcpKeepConn(TcpKeepConn* conn)
}
/**
* @brief IP地址缓存TCP的保持连接
*/
bool TcpKeepMgr::CacheTcpKeepConn(TcpKeepConn* conn)
{
struct sockaddr_in* dst = conn->GetDestAddr();
@ -672,9 +578,6 @@ bool TcpKeepMgr::CacheTcpKeepConn(TcpKeepConn* conn)
}
/**
* @brief tcp长连接
*/
void TcpKeepMgr::FreeTcpKeepConn(TcpKeepConn* conn, bool force_free)
{
if (force_free)
@ -693,16 +596,9 @@ void TcpKeepMgr::FreeTcpKeepConn(TcpKeepConn* conn, bool force_free)
}
}
}
/**
* @brief socket建立,
* @return >0 -, fd, < 0
*/
int UdpSessionConn::CreateSocket()
{
// 1. session连接类, 由通知对象创建管理fd
if (!_action || !_ntfy_obj) {
MTLOG_ERROR("conn not set action %p, or _ntfy_obj %p, error", _action, _ntfy_obj);
return -100;
@ -718,7 +614,6 @@ int UdpSessionConn::CreateSocket()
return -300;
}
// 2. 委派创建, 更新句柄信息
int osfd = real_ntfy->GetOsfd();
if (osfd <= 0)
{
@ -733,19 +628,11 @@ int UdpSessionConn::CreateSocket()
return osfd;
}
/**
* @brief socket,
*/
int UdpSessionConn::CloseSocket()
{
return 0;
}
/**
* @brief ,
* @return 0 , . <0 . >0
*/
int UdpSessionConn::SendData()
{
if (!_action || !_msg_buff || !_ntfy_obj) {
@ -776,11 +663,6 @@ int UdpSessionConn::SendData()
}
}
/**
* @brief ,
* @param buff
* @return 0 -; >0 ; < 0
*/
int UdpSessionConn::RecvData()
{
if (!_ntfy_obj || !_msg_buff) {
@ -793,7 +675,6 @@ int UdpSessionConn::RecvData()
return 0;
}
// UDP Session 通知会替换msg buff, 通过type判定
int msg_len = _msg_buff->GetMsgLen();
if (BUFF_RECV == _msg_buff->GetBuffType())
{
@ -806,11 +687,6 @@ int UdpSessionConn::RecvData()
}
}
/**
* @brief session全局管理句柄
* @return
*/
ConnectionMgr* ConnectionMgr::_instance = NULL;
ConnectionMgr* ConnectionMgr::Instance (void)
{
@ -822,9 +698,6 @@ ConnectionMgr* ConnectionMgr::Instance (void)
return _instance;
}
/**
* @brief session管理全局的销毁接口
*/
void ConnectionMgr::Destroy()
{
if( _instance != NULL )
@ -834,23 +707,14 @@ void ConnectionMgr::Destroy()
}
}
/**
* @brief buff的构造函数
*/
ConnectionMgr::ConnectionMgr()
{
}
/**
* @brief , ,
*/
ConnectionMgr::~ConnectionMgr()
{
}
/**
* @brief
*/
IMtConnection* ConnectionMgr::GetConnection(CONN_OBJ_TYPE type, struct sockaddr_in* dst)
{
switch (type)
@ -874,9 +738,6 @@ IMtConnection* ConnectionMgr::GetConnection(CONN_OBJ_TYPE type, struct sockaddr_
}
/**
* @brief
*/
void ConnectionMgr::FreeConnection(IMtConnection* conn, bool force_free)
{
if (!conn) {
@ -908,14 +769,8 @@ void ConnectionMgr::FreeConnection(IMtConnection* conn, bool force_free)
return;
}
/**
* @brief idle的tcp长连接
*/
void ConnectionMgr::CloseIdleTcpKeep(TcpKeepConn* conn)
{
_tcp_keep_mgr.RemoveTcpKeepConn(conn);
_tcp_keep_mgr.FreeTcpKeepConn(conn, true);
}

View File

@ -19,7 +19,6 @@
/**
* @file mt_connection.h
* @info 线
* @time 20130924
**/
@ -36,140 +35,75 @@ namespace NS_MICRO_THREAD {
using std::queue;
/**
* @brief
*/
enum CONN_OBJ_TYPE
{
OBJ_CONN_UNDEF = 0, ///< 未定义的连接对象
OBJ_SHORT_CONN = 1, ///< 短连接对象, fd关联会话, 每次用完CLOSE
OBJ_TCP_KEEP = 2, ///< TCP的复用模型, 每次每连接使用该fd, 用完可复用
OBJ_UDP_SESSION = 3, ///< UDP的session模型, 每连接可供任意线程使用
OBJ_CONN_UNDEF = 0,
OBJ_SHORT_CONN = 1,
OBJ_TCP_KEEP = 2,
OBJ_UDP_SESSION = 3,
};
/**
* @brief 线,
*/
class IMtConnection
{
public:
/**
* @brief 线
*/
IMtConnection();
virtual ~IMtConnection();
/**
* @brief
*/
virtual void Reset();
/**
* @brief
*/
CONN_OBJ_TYPE GetConnType() {
return _type;
};
/**
* @brief ACTION指针
* @return IMtConn指针
*/
void SetIMtActon(IMtAction* action ) {
_action = action;
};
/**
* @brief ACTION指针
* @return IMtConn指针
*/
IMtAction* GetIMtActon() {
return _action;
};
/**
* @brief ACTION指针
* @return IMtConn指针
*/
void SetNtfyObj(KqueuerObj* obj ) {
_ntfy_obj = obj;
};
/**
* @brief ACTION指针
* @return IMtConn指针
*/
KqueuerObj* GetNtfyObj() {
return _ntfy_obj;
};
/**
* @brief msgbuff指针
* @return IMtConn指针
*/
void SetMtMsgBuff(MtMsgBuf* msg_buf) {
_msg_buff = msg_buf;
};
/**
* @brief msgbuff指针
* @return IMtConn指针
*/
MtMsgBuf* GetMtMsgBuff() {
return _msg_buff;
};
public:
/**
* @brief socket建立,
* @return >0 -, fd, < 0
*/
virtual int CreateSocket() {return 0;};
/**
* @brief , TCP的connect等
* @return 0 -, < 0
*/
virtual int OpenCnnect() {return 0;};
/**
* @brief
* @return >0 -, , < 0
*/
virtual int SendData() {return 0;};
/**
* @brief
* @return >0 -, , < 0 (-1 ; -2 )
*/
virtual int RecvData() {return 0;};
/**
* @brief socket端口
* @return >0 -, fd, < 0
*/
virtual int CloseSocket() {return 0;};
protected:
CONN_OBJ_TYPE _type; // 预置的type, 可按type做工厂管理
IMtAction* _action; // 关联的action指针, 上级指针, 不关心资源生存期
KqueuerObj* _ntfy_obj; // EPOLL通知对象, 下级指针, 关心生存期
MtMsgBuf* _msg_buff; // 动态管理的buff字段, 下级指针, 关心生存期
CONN_OBJ_TYPE _type;
IMtAction* _action;
KqueuerObj* _ntfy_obj;
MtMsgBuf* _msg_buff;
};
/**
* @brief sock的短连接类型
*/
class UdpShortConn : public IMtConnection
{
public:
/**
* @brief socket的短连接的构造与析构
*/
UdpShortConn() {
_osfd = -1;
_type = OBJ_SHORT_CONN;
@ -178,37 +112,18 @@ public:
CloseSocket();
};
/**
* @brief
*/
virtual void Reset();
/**
* @brief socket建立,
* @return >0 -, fd, < 0
*/
virtual int CreateSocket();
/**
* @brief
* @return >0 -, , < 0
*/
virtual int SendData();
/**
* @brief
* @return >0 -, , < 0 (-1 ; -2 )
*/
virtual int RecvData();
/**
* @brief socket端口
* @return >0 -, fd, < 0
*/
virtual int CloseSocket();
protected:
int _osfd; // 每次连接单独创建socket
int _osfd;
};
@ -218,64 +133,36 @@ enum TcpKeepFlag
TCP_KEEP_IN_KQUEUE = 0x2,
};
/**
* @brief session的UDP复用连接
*/
class UdpSessionConn : public IMtConnection
{
public:
/**
* @brief socket的短连接的构造与析构
*/
UdpSessionConn() {
_type = OBJ_UDP_SESSION;
};
virtual ~UdpSessionConn() { };
/**
* @brief socket建立,
* @return >0 -, fd, < 0
*/
virtual int CreateSocket();
/**
* @brief
* @return >0 -, , < 0
*/
virtual int SendData();
/**
* @brief
* @return >0 -, , < 0 (-1 ; -2 )
*/
virtual int RecvData();
/**
* @brief socket端口
* @return >0 -, fd, < 0
*/
virtual int CloseSocket();
};
/**
* @brief sock的TCP复用连接
*/
typedef TAILQ_ENTRY(TcpKeepConn) KeepConnLink;
typedef TAILQ_HEAD(__KeepConnTailq, TcpKeepConn) KeepConnList;
class TcpKeepConn : public IMtConnection, public CTimerNotify
{
public:
int _keep_flag; // 队列状态标记
KeepConnLink _keep_entry; // 队列管理入口
int _keep_flag;
KeepConnLink _keep_entry;
/**
* @brief socket的短连接的构造与析构
*/
TcpKeepConn() {
_osfd = -1;
_keep_time = 10*60*1000; // 默认10分钟, 可以按需调整
_keep_time = 10*60*1000;
_keep_flag = 0;
_type = OBJ_TCP_KEEP;
_keep_ntfy.SetKeepNtfyObj(this);
@ -284,102 +171,51 @@ public:
CloseSocket();
};
/**
* @brief
*/
virtual void Reset();
/**
* @brief , TCP的connect等
* @return 0 -, < 0
*/
virtual int OpenCnnect();
/**
* @brief socket建立,
* @return >0 -, fd, < 0
*/
virtual int CreateSocket();
/**
* @brief
* @return >0 -, , < 0
*/
virtual int SendData();
/**
* @brief
* @return >0 -, , < 0 (-1 ; -2 )
*/
virtual int RecvData();
/**
* @brief socket端口
* @return >0 -, fd, < 0
*/
virtual int CloseSocket();
/**
* @brief
*/
void ConnReuseClean();
/**
* @brief Idle缓存处理, epoll
*/
bool IdleAttach();
/**
* @brief Idle取消缓存处理, 线
*/
bool IdleDetach();
/**
* @brief ,
*/
void SetDestAddr(struct sockaddr_in* dst) {
memcpy(&_dst_addr, dst, sizeof(_dst_addr));
}
/**
* @brief
*/
struct sockaddr_in* GetDestAddr() {
return &_dst_addr;
}
/**
* @brief ,
*/
virtual void timer_notify();
/**
* @brief ,
*/
void SetKeepTime(unsigned int time) {
_keep_time = time;
};
protected:
int _osfd; // 每次连接单独创建socket
unsigned int _keep_time; // 设置保活的时间
TcpKeepNtfy _keep_ntfy; // 关联一个保活连接对象
struct sockaddr_in _dst_addr; // 远端地址信息
int _osfd;
unsigned int _keep_time;
TcpKeepNtfy _keep_ntfy;
struct sockaddr_in _dst_addr;
};
/**
* @brief hash缓存长连接
*/
class TcpKeepKey : public HashKey
{
public:
/**
* @brief
*/
TcpKeepKey() {
_addr_ipv4 = 0;
_net_port = 0;
@ -394,25 +230,14 @@ public:
this->SetDataPtr(this);
};
/**
* @brief conn
*/
~TcpKeepKey() {
TAILQ_INIT(&_keep_list);
};
/**
* @brief hash算法, key的hash值
* @return hash值
*/
virtual uint32_t HashValue(){
return _addr_ipv4 ^ ((_net_port << 16) | _net_port);
};
/**
* @brief cmp方法, ID下, key比较
* @return hash值
*/
virtual int HashCmp(HashKey* rhs){
TcpKeepKey* data = dynamic_cast<TcpKeepKey*>(rhs);
if (!data) {
@ -427,10 +252,6 @@ public:
return 0;
};
/**
* @brief
*/
void InsertConn(TcpKeepConn* conn) {
if (conn->_keep_flag & TCP_KEEP_IN_LIST) {
return;
@ -452,60 +273,36 @@ public:
};
private:
uint32_t _addr_ipv4; ///< ip地址
uint16_t _net_port; ///< port 网络序列
KeepConnList _keep_list; ///< 实际的空闲队列
uint32_t _addr_ipv4;
uint16_t _net_port;
KeepConnList _keep_list;
};
/**
* @brief TCP长连接的连接对象管理与内存cache
*/
class TcpKeepMgr
{
public:
typedef CPtrPool<TcpKeepConn> TcpKeepQueue; ///< 内存缓冲池
typedef CPtrPool<TcpKeepConn> TcpKeepQueue;
/**
* @brief
*/
TcpKeepMgr();
~TcpKeepMgr();
/**
* @brief IP地址获取TCP的保持连接
*/
TcpKeepConn* GetTcpKeepConn(struct sockaddr_in* dst);
/**
* @brief IP地址缓存TCP的保持连接
*/
bool CacheTcpKeepConn(TcpKeepConn* conn);
/**
* @brief IP地址缓存TCP的保持连接, CACHE
*/
bool RemoveTcpKeepConn(TcpKeepConn* conn);
/**
* @brief tcp长连接
*/
void FreeTcpKeepConn(TcpKeepConn* conn, bool force_free);
private:
HashList* _keep_hash; ///< hash表, 存储按IP索引的连接队列
TcpKeepQueue _mem_queue; ///< mem队列, 管理conn内存块
HashList* _keep_hash;
TcpKeepQueue _mem_queue;
};
/**
* @brief
*/
class ConnectionMgr
{
public:
@ -513,48 +310,26 @@ public:
typedef CPtrPool<UdpShortConn> UdpShortQueue;
typedef CPtrPool<UdpSessionConn> UdpSessionQueue;
/**
* @brief buff的全局管理句柄接口
* @return
*/
static ConnectionMgr* Instance (void);
/**
* @brief
*/
static void Destroy(void);
/**
* @brief
*/
IMtConnection* GetConnection(CONN_OBJ_TYPE type, struct sockaddr_in* dst);
/**
* @brief
*/
void FreeConnection(IMtConnection* conn, bool force_free);
/**
* @brief idle的tcp长连接
*/
void CloseIdleTcpKeep(TcpKeepConn* conn);
/**
* @brief buff的析构函数
*/
~ConnectionMgr();
private:
/**
* @brief buff的构造函数
*/
ConnectionMgr();
static ConnectionMgr * _instance; ///< 单例类句柄
static ConnectionMgr * _instance;
UdpShortQueue _udp_short_queue; ///< 短连接的队列池
UdpSessionQueue _udp_session_queue; ///< udp session 连接池
TcpKeepMgr _tcp_keep_mgr; ///< tcp keep 管理器
UdpShortQueue _udp_short_queue;
UdpSessionQueue _udp_session_queue;
TcpKeepMgr _tcp_keep_mgr;
};
}

View File

@ -19,7 +19,6 @@
/**
* @file mt_incl.h
* @info 线spp_plugin的头文件
* @time 20130924
*/

View File

@ -19,7 +19,6 @@
/**
* @file mt_mbuf_pool.cpp
* @info 线buf池管理实现
* @time 20130924
**/
@ -29,11 +28,6 @@
using namespace std;
using namespace NS_MICRO_THREAD;
/**
* @brief 访
* @return
*/
MsgBuffPool* MsgBuffPool::_instance = NULL;
MsgBuffPool* MsgBuffPool::Instance (void)
{
@ -45,9 +39,6 @@ MsgBuffPool* MsgBuffPool::Instance (void)
return _instance;
}
/**
* @brief
*/
void MsgBuffPool::Destroy()
{
if( _instance != NULL )
@ -57,19 +48,12 @@ void MsgBuffPool::Destroy()
}
}
/**
* @brief buff的构造函数
*/
MsgBuffPool::MsgBuffPool(int max_free)
{
_max_free = max_free;
_hash_map = new HashList(10000);
}
/**
* @brief buff的析构函数
*/
MsgBuffPool::~MsgBuffPool()
{
if (!_hash_map) {
@ -91,10 +75,6 @@ MsgBuffPool::~MsgBuffPool()
_hash_map = NULL;
}
/**
* @brief buff元素
* @return msgbuf指针, NULL
*/
MtMsgBuf* MsgBuffPool::GetMsgBuf(int max_size)
{
if (!_hash_map) {
@ -127,10 +107,6 @@ MtMsgBuf* MsgBuffPool::GetMsgBuf(int max_size)
}
}
/**
* @brief buff元素
* @return msgbuf指针, NULL
*/
void MsgBuffPool::FreeMsgBuf(MtMsgBuf* msg_buf)
{
if (!_hash_map || !msg_buf) {

View File

@ -19,7 +19,6 @@
/**
* @file mt_mbuf_pool.h
* @info 线buf池
**/
#ifndef __MT_MBUF_POOL_H__
@ -35,33 +34,27 @@ using std::queue;
enum BUFF_TYPE
{
BUFF_UNDEF = 0, ///< 未定义类型
BUFF_RECV = 1, ///< 接收buff
BUFF_SEND = 2, ///< 发送buff
BUFF_UNDEF = 0,
BUFF_RECV = 1,
BUFF_SEND = 2,
};
/**
* @brief buffer类
*/
typedef TAILQ_ENTRY(MtMsgBuf) MsgBufLink;
typedef TAILQ_HEAD(__MtbuffTailq, MtMsgBuf) MsgBufQueue;
class MtMsgBuf
{
private:
int _max_len; // 最大的空间长度
int _msg_len; // 实际的消息长度
int _buf_type; // buff是发送还是接收
int _recv_len; // 已接收的消息长度
int _send_len; // 已发送的消息长度
void* _msg_buff; // buffer 实际头指针
int _max_len;
int _msg_len;
int _buf_type;
int _recv_len;
int _send_len;
void* _msg_buff;
public:
MsgBufLink _entry;
/**
* @brief , buff长度
*/
MtMsgBuf(int max_len) {
_max_len = max_len;
_msg_len = 0;
@ -78,9 +71,6 @@ public:
}
};
/**
* @brief
*/
void SetBuffType(BUFF_TYPE type) {
_buf_type = (int)type;
};
@ -88,9 +78,6 @@ public:
return (BUFF_TYPE)_buf_type;
};
/**
* @brief ,
*/
void Reset() {
_msg_len = 0;
_recv_len = 0;
@ -98,9 +85,6 @@ public:
_buf_type = BUFF_UNDEF;
};
/**
* @brief
*/
void SetMsgLen(int msg_len) {
_msg_len = msg_len;
};
@ -108,9 +92,6 @@ public:
return _msg_len;
};
/**
* @brief buffer指针获取
*/
int GetMaxLen() {
return _max_len;
};
@ -118,9 +99,6 @@ public:
return _msg_buff;
};
/**
* @brief
*/
int GetHaveSndLen() {
return _send_len;
};
@ -128,9 +106,7 @@ public:
_send_len = snd_len;
};
/**
* @brief
*/
int GetHaveRcvLen() {
return _recv_len;
};
@ -139,18 +115,10 @@ public:
};
};
/**
* @brief buffer,
*/
class MsgBufMap : public HashKey
{
public:
/**
* @brief buff管理的构造
* @param buff_size map元素上的所有buff, buff空间大小值
* @param max_free , free数目
*/
MsgBufMap(int buff_size, int max_free) {
_max_buf_size = buff_size;
_max_free = max_free;
@ -159,18 +127,11 @@ public:
TAILQ_INIT(&_msg_queue);
};
/**
* @brief buff管理的构造, , key信息
* @param buff_size map元素上的所有buff, buff空间大小值
*/
explicit MsgBufMap(int buff_size) {
_max_buf_size = buff_size;
TAILQ_INIT(&_msg_queue);
};
/**
* @brief buff管理的析构清理
*/
~MsgBufMap() {
MtMsgBuf* ptr = NULL;
MtMsgBuf* tmp = NULL;
@ -183,11 +144,7 @@ public:
TAILQ_INIT(&_msg_queue);
};
/**
* @brief buff元素
* @return msgbuf指针, NULL
*/
MtMsgBuf* GetMsgBuf(){
MtMsgBuf* ptr = NULL;
if (!TAILQ_EMPTY(&_msg_queue)) {
@ -201,10 +158,6 @@ public:
return ptr;
};
/**
* @brief buff元素
* @param msgbuf指针
*/
void FreeMsgBuf(MtMsgBuf* ptr){
if (_queue_num >= _max_free) {
delete ptr;
@ -215,88 +168,49 @@ public:
}
};
/**
* @brief hash算法, key的hash值
* @return hash值
*/
virtual uint32_t HashValue(){
return _max_buf_size;
};
/**
* @brief cmp方法, ID下, key比较
* @return hash值
*/
virtual int HashCmp(HashKey* rhs){
return this->_max_buf_size - (int)rhs->HashValue();
};
private:
int _max_free; ///< 最大空闲保留个数
int _max_buf_size; ///< 本队列最大的buffsize
int _queue_num; ///< 空闲队列个数
MsgBufQueue _msg_queue; ///< 实际的空闲队列
int _max_free;
int _max_buf_size;
int _queue_num;
MsgBufQueue _msg_queue;
};
/**
* @brief buffer池对象, buffer
*/
class MsgBuffPool
{
public:
/**
* @brief buff的全局管理句柄接口
* @return
*/
static MsgBuffPool* Instance (void);
/**
* @brief
*/
static void Destroy(void);
/**
* @brief buff的全局管理设置默认最大的空闲个数
* @param max_free ,
*/
void SetMaxFreeNum(int max_free) {
_max_free = max_free;
};
/**
* @brief buff元素
* @return msgbuf指针, NULL
*/
MtMsgBuf* GetMsgBuf(int max_size);
/**
* @brief buff元素
* @param msgbuf指针
*/
void FreeMsgBuf(MtMsgBuf* msg_buf);
/**
* @brief buff的全局类析构函数
*/
~MsgBuffPool();
private:
/**
* @brief buff的构造函数
*/
explicit MsgBuffPool(int max_free = 300);
static MsgBuffPool * _instance; ///< 单例类句柄
int _max_free; ///< 最大保留空闲数目
HashList* _hash_map; ///< 按size hashmap 保存空闲队列
static MsgBuffPool * _instance;
int _max_free;
HashList* _hash_map;
};
}
#endif

View File

@ -19,7 +19,6 @@
/**
* @file mt_msg.h
* @info 线
**/
#ifndef __MT_MSG_H__
@ -27,22 +26,12 @@
namespace NS_MICRO_THREAD {
/**
* @brief 线
*/
class IMtMsg
{
public:
/**
* @brief 线
* @return 0 -, < 0
*/
virtual int HandleProcess() { return -1; };
/**
* @brief 线
*/
IMtMsg() {};
virtual ~IMtMsg() {};
};

File diff suppressed because it is too large Load Diff

View File

@ -19,7 +19,6 @@
/**
* @file mt_net.h
* @info 线
**/
#ifndef __MT_NET_H__
@ -33,41 +32,28 @@
namespace NS_MICRO_THREAD {
/**
* @brief
*/
enum MT_CONN_TYPE
{
TYPE_CONN_UNKNOWN = 0,
TYPE_CONN_SHORT = 0x1, ///< 短连接, 一次交互后关闭
TYPE_CONN_POOL = 0x2, ///< 长连接,每次使用后, 可回收重复使用
TYPE_CONN_SESSION = 0x4, ///< 长连接按session id 复用, 防串包
TYPE_CONN_SENDONLY = 0x8, ///< 只发不收
TYPE_CONN_SHORT = 0x1,
TYPE_CONN_POOL = 0x2,
TYPE_CONN_SESSION = 0x4,
TYPE_CONN_SENDONLY = 0x8,
};
/******************************************************************************/
/* 内部实现部分 */
/******************************************************************************/
class CSockLink;
/**
* @brief
* @info List必须是tailq, Type reset函数, releasetime, linkentry字段
*/
template <typename List, typename Type>
class CRecyclePool
{
public:
// 构造函数, 默认60s超时
CRecyclePool() {
_expired = 60 * 1000;
_count = 0;
TAILQ_INIT(&_free_list);
};
// 析构函数, 删除池中元素
~CRecyclePool() {
Type* item = NULL;
Type* tmp = NULL;
@ -79,7 +65,6 @@ public:
_count = 0;
};
// 复用或新创建对象
Type* AllocItem() {
Type* item = TAILQ_FIRST(&_free_list);
if (item != NULL)
@ -98,16 +83,13 @@ public:
return item;
};
// 释放管理对象
void FreeItem(Type* obj) {
//obj->Reset();
TAILQ_INSERT_TAIL(&_free_list, obj, _link_entry);
obj->_release_time = mt_time_ms();
_count++;
};
// 回收句柄
void RecycleItem(uint64_t now) {
Type* item = NULL;
Type* tmp = NULL;
@ -123,28 +105,21 @@ public:
}
};
// 设置自定义的超时时间
void SetExpiredTime(uint64_t expired) {
_expired = expired;
};
private:
List _free_list; ///< 空闲链表
uint64_t _expired; ///< 超时时间
uint32_t _count; ///< 元素计数
List _free_list;
uint64_t _expired;
uint32_t _count;
};
/**
* @brief IO关联一个句柄对象
*/
class CNetHandler : public HashKey
{
public:
// 句柄状态描述
enum {
STATE_IN_SESSION = 0x1,
STATE_IN_CONNECT = 0x2,
@ -152,23 +127,13 @@ public:
STATE_IN_RECV = 0x8,
STATE_IN_IDLE = 0x10,
};
/**
* @brief hash算法, key的hash值
* @return hash值
*/
virtual uint32_t HashValue();
/**
* @brief cmp方法, ID下, key比较
* @return hash值
*/
virtual int HashCmp(HashKey* rhs);
// 同步收发接口
int32_t SendRecv(void* data, uint32_t len, uint32_t timeout);
// 获取返回buff信息, 有效期直到helper析构
void* GetRspBuff() {
if (_rsp_buff != NULL) {
return _rsp_buff->data;
@ -177,7 +142,6 @@ public:
}
};
// 获取返回buff信息, 有效期直到helper析构
uint32_t GetRspLen() {
if (_rsp_buff != NULL) {
return _rsp_buff->data_len;
@ -185,8 +149,7 @@ public:
return 0;
}
};
// 设置rsp信息
void SetRespBuff(TSkBuffer* buff) {
if (_rsp_buff != NULL) {
delete_sk_buffer(_rsp_buff);
@ -196,34 +159,28 @@ public:
_rsp_buff = buff;
};
// 设置协议的类型, 默认UDP
void SetProtoType(MT_PROTO_TYPE type) {
_proto_type = type;
};
// 设置连接类型, 默认长连接
void SetConnType(MT_CONN_TYPE type) {
_conn_type = type;
};
// 设置目的IP地址
void SetDestAddress(struct sockaddr_in* dst) {
if (dst != NULL) {
memcpy(&_dest_ipv4, dst, sizeof(*dst));
}
};
// 设置session本次session id信息, 必须非0
void SetSessionId(uint64_t sid) {
_session_id = sid;
};
// 设置session解析回调函数
void SetSessionCallback(CHECK_SESSION_CALLBACK function) {
_callback = function;
};
// 获取回调函数信息
CHECK_SESSION_CALLBACK GetSessionCallback() {
return _callback;
};
@ -231,113 +188,86 @@ public:
public:
// 关联连接对象
void Link(CSockLink* conn);
// 解耦连接对象
void Unlink();
// 检查必要的参数信息
int32_t CheckParams();
// 获取链接, 同时关联到等待连接的队列中
int32_t GetConnLink();
// 检查必要的参数信息
int32_t WaitConnect(uint64_t timeout);
// 检查必要的参数信息
int32_t WaitSend(uint64_t timeout);
// 检查必要的参数信息
int32_t WaitRecv(uint64_t timeout);
// 关联在等待连接队列
void SwitchToConn();
// 切换到发送队列
void SwitchToSend();
// 切换到接收队列
void SwitchToRecv();
// 切换到空闲状态
void SwitchToIdle();
// 解耦连接对象
void DetachConn();
// 注册session管理
bool RegistSession();
// 取消注册session
void UnRegistSession();
// 跳过发送的请求长度
uint32_t SkipSendPos(uint32_t len);
// 设置返回码
void SetErrNo(int32_t err) {
_err_no = err;
};
// 获取关联的线程信息
MicroThread* GetThread() {
return _thread;
};
// 获取待发送的指针与数据长度
void GetSendData(void*& data, uint32_t& len) {
data = _req_data;
len = _req_len;
};
// 复用接口
void Reset();
// 构造与析构
CNetHandler();
~CNetHandler();
// 队列快捷访问的宏定义
TAILQ_ENTRY(CNetHandler) _link_entry;
uint64_t _release_time;
protected:
MicroThread* _thread; ///< 关联线程指针对象
MT_PROTO_TYPE _proto_type; ///< 协议类型
MT_CONN_TYPE _conn_type; ///< 连接类型
struct sockaddr_in _dest_ipv4; ///< ipv4目的地址
uint64_t _session_id; ///< 会话ID
CHECK_SESSION_CALLBACK _callback; ///< 会话提取回调函数
uint32_t _state_flags; ///< 内部状态字段
int32_t _err_no; ///< 返回码信息
void* _conn_ptr; ///< socket 链路指针
uint32_t _send_pos; ///< 已发送的pos位置
uint32_t _req_len; ///< 请求包长度
void* _req_data; ///< 请求包指针
TSkBuffer* _rsp_buff; ///< 应答buff信息
MicroThread* _thread;
MT_PROTO_TYPE _proto_type;
MT_CONN_TYPE _conn_type;
struct sockaddr_in _dest_ipv4;
uint64_t _session_id;
CHECK_SESSION_CALLBACK _callback;
uint32_t _state_flags;
int32_t _err_no;
void* _conn_ptr;
uint32_t _send_pos;
uint32_t _req_len;
void* _req_data;
TSkBuffer* _rsp_buff;
};
typedef TAILQ_HEAD(__NetHandlerList, CNetHandler) TNetItemList; ///< 高效的双链管理
typedef CRecyclePool<TNetItemList, CNetHandler> TNetItemPool; ///< 定时回收的对象池
typedef TAILQ_HEAD(__NetHandlerList, CNetHandler) TNetItemList;
typedef CRecyclePool<TNetItemList, CNetHandler> TNetItemPool;
/**
* @brief
*/
class CSockLink : public KqueuerObj
{
public:
// 句柄状态描述
enum {
LINK_CONNECTING = 0x1,
LINK_CONNECTED = 0x2,
};
// 状态队列定义
enum {
LINK_IDLE_LIST = 1,
LINK_CONN_LIST = 2,
@ -345,115 +275,74 @@ public:
LINK_RECV_LIST = 4,
};
// 检查或创建socket句柄
int32_t CreateSock();
// 关闭链路的句柄
void Close();
// 发起连接过程
bool Connect();
bool Connected() {
return (_state & LINK_CONNECTED);
}
// 异常终止的处理函数
void Destroy();
// 获取管理链表
TNetItemList* GetItemList(int32_t type);
// 管理句柄信息
void AppendToList(int32_t type, CNetHandler* item);
// 管理句柄信息
void RemoveFromList(int32_t type, CNetHandler* item);
// 获取目标ip信息
struct sockaddr_in* GetDestAddr(struct sockaddr_in* addr);
// 发起连接过程
int32_t SendData(void* data, uint32_t len);
// udp发送数据
int32_t SendCacheUdp(void* data, uint32_t len);
// tcp发送数据
int32_t SendCacheTcp(void* data, uint32_t len);
// 尝试接收更多的数据到临时buff
void ExtendRecvRsp();
// 数据分发处理过程
int32_t RecvDispath();
// 或者回调函数, 优先从排队等待中获取, 备份从父节点获取
CHECK_SESSION_CALLBACK GetSessionCallback();
// TCP接收数据流处理与分发
int32_t DispathTcp();
// UDP接收数据流处理与分发
int32_t DispathUdp();
// 查询本地sessionid关联的session信息
CNetHandler* FindSession(uint64_t sid);
/**
* @brief , ,
* @return 0 fd可继续处理其它事件; !=0 fd需跳出回调处理
*/
virtual int InputNotify();
/**
* @brief , ,
* @return 0 fd可继续处理其它事件; !=0 fd需跳出回调处理
*/
virtual int OutputNotify();
/**
* @brief
* @return ,
*/
virtual int HangupNotify();
// 构造与析构函数
CSockLink();
~CSockLink();
// 清理置初始化逻辑
~CSockLink();
void Reset();
// 通知唤醒线程
void NotifyThread(CNetHandler* item, int32_t result);
// 通知唤醒线程
void NotifyAll(int32_t result);
// 设置协议类型, 决定buff池的指针
void SetProtoType(MT_PROTO_TYPE type);
// 设置上级指针信息
void SetParentsPtr(void* ptr) {
_parents = ptr;
};
// 获取上级节点指针
void* GetParentsPtr() {
return _parents;
};
// 获取上次的访问时间
uint64_t GetLastAccess() {
return _last_access;
};
public:
// 队列快捷访问的宏定义
TAILQ_ENTRY(CSockLink) _link_entry;
uint64_t _release_time;
@ -471,44 +360,32 @@ private:
TSkBuffer* _rsp_buff;
void* _parents;
};
typedef TAILQ_HEAD(__SocklinkList, CSockLink) TLinkList; ///< 高效的双链管理
typedef CRecyclePool<TLinkList, CSockLink> TLinkPool; ///< 定时回收的对象池
typedef TAILQ_HEAD(__SocklinkList, CSockLink) TLinkList;
typedef CRecyclePool<TLinkList, CSockLink> TLinkPool;
class CDestLinks : public CTimerNotify, public HashKey
{
public:
// 构造函数
CDestLinks();
// 析构函数
~CDestLinks();
// 重置复用的接口函数
void Reset();
// 启动定时器
void StartTimer();
// 获取一个连接link, 暂时按轮询
CSockLink* GetSockLink();
// 释放一个连接link
void FreeSockLink(CSockLink* sock);
// 获取协议类型
MT_PROTO_TYPE GetProtoType() {
return _proto_type;
};
// 获取连接类型
MT_CONN_TYPE GetConnType() {
return _conn_type;
};
// 设置关键信息
void SetKeyInfo(uint32_t ipv4, uint16_t port, MT_PROTO_TYPE proto, MT_CONN_TYPE conn) {
_addr_ipv4 = ipv4;
_net_port = port;
@ -516,37 +393,24 @@ public:
_conn_type = conn;
};
// 拷贝KEY信息
void CopyKeyInfo(CDestLinks* key) {
_addr_ipv4 = key->_addr_ipv4;
_net_port = key->_net_port;
_proto_type = key->_proto_type;
_conn_type = key->_conn_type;
};
// 获取IP port信息
void GetDestIP(uint32_t& ip, uint16_t& port) {
ip = _addr_ipv4;
port = _net_port;
};
/**
* @brief , ,
*/
virtual void timer_notify();
/**
* @brief hash算法, key的hash值
* @return hash值
*/
virtual uint32_t HashValue() {
return _addr_ipv4 ^ (((uint32_t)_net_port << 16) | (_proto_type << 8) | _conn_type);
};
/**
* @brief cmp方法, ID下, key比较
* @return hash值
*/
virtual int HashCmp(HashKey* rhs) {
CDestLinks* data = (CDestLinks*)(rhs);
if (!data) {
@ -568,120 +432,86 @@ public:
return 0;
};
// 设置session解析回调函数
void SetDefaultCallback(CHECK_SESSION_CALLBACK function) {
_dflt_callback = function;
};
// 获取回调函数信息
CHECK_SESSION_CALLBACK GetDefaultCallback() {
return _dflt_callback;
};
// 队列快捷访问的宏定义
TAILQ_ENTRY(CDestLinks) _link_entry;
uint64_t _release_time;
private:
uint32_t _timeout; ///< idle的超时时间
uint32_t _addr_ipv4; ///< ip地址
uint16_t _net_port; ///< port 网络序列
MT_PROTO_TYPE _proto_type; ///< 协议类型
MT_CONN_TYPE _conn_type; ///< 连接类型
uint32_t _timeout;
uint32_t _addr_ipv4;
uint16_t _net_port;
MT_PROTO_TYPE _proto_type;
MT_CONN_TYPE _conn_type;
uint32_t _max_links; ///< 最大连接数
uint32_t _curr_link; ///< 当前连接数
TLinkList _sock_list; ///< 连接链表
CHECK_SESSION_CALLBACK _dflt_callback; ///< 默认的check函数
uint32_t _max_links;
uint32_t _curr_link;
TLinkList _sock_list;
CHECK_SESSION_CALLBACK _dflt_callback;
};
typedef TAILQ_HEAD(__DestlinkList, CDestLinks) TDestList; ///< 高效的双链管理
typedef CRecyclePool<TDestList, CDestLinks> TDestPool; ///< 定时回收的对象池
typedef TAILQ_HEAD(__DestlinkList, CDestLinks) TDestList;
typedef CRecyclePool<TDestList, CDestLinks> TDestPool;
/**
* @brief
*/
class CNetMgr
{
public:
/**
* @brief buff的全局管理句柄接口
* @return
*/
static CNetMgr* Instance (void);
/**
* @brief
*/
static void Destroy(void);
// 查询是否已经存在同一个sid的对象
CNetHandler* FindNetItem(CNetHandler* key);
// 注册一个item, 先查询后插入, 保证无冲突
void InsertNetItem(CNetHandler* item);
// 移除一个item对象
void RemoveNetItem(CNetHandler* item);
// 查询或创建一个目标ip的links节点
CDestLinks* FindCreateDest(CDestLinks* key);
// 删除掉已有的目标链路信息
void DeleteDestLink(CDestLinks* dst);
// 查询是否已经存在同一个sid的对象
CDestLinks* FindDestLink(CDestLinks* key);
// 注册一个item, 先查询后插入, 保证无冲突
void InsertDestLink(CDestLinks* item);
// 移除一个item对象
void RemoveDestLink(CDestLinks* item);
/**
* @brief buff的析构函数
*/
~CNetMgr();
/**
* @brief
*/
void RecycleObjs(uint64_t now);
// 分配一个网络管理句柄
CNetHandler* AllocNetItem() {
return _net_item_pool.AllocItem();
};
// 释放一个网络管理句柄
void FreeNetItem(CNetHandler* item) {
return _net_item_pool.FreeItem(item);
};
// 分配一个SOCK连接链路
CSockLink* AllocSockLink() {
return _sock_link_pool.AllocItem();
};
// 释放一个SOCK连接链路
void FreeSockLink(CSockLink* item) {
return _sock_link_pool.FreeItem(item);
};
// 分配一个SOCK连接链路
CDestLinks* AllocDestLink() {
return _dest_ip_pool.AllocItem();
};
// 释放一个SOCK连接链路
void FreeDestLink(CDestLinks* item) {
return _dest_ip_pool.FreeItem(item);
};
// 获取udp的buff池信息
TSkBuffMng* GetSkBuffMng(MT_PROTO_TYPE type) {
if (type == NET_PROTO_TCP) {
return &_tcp_pool;
@ -692,25 +522,18 @@ public:
private:
/**
* @brief buff的构造函数
*/
CNetMgr();
static CNetMgr * _instance; ///< 单例类句柄
HashList* _ip_hash; ///< 目的地址hash
HashList* _session_hash; ///< session id的hash
TSkBuffMng _udp_pool; ///< udp pool, 64K
TSkBuffMng _tcp_pool; ///< tcp pool, 4K
TDestPool _dest_ip_pool; ///< 目的ip对象池
TLinkPool _sock_link_pool; ///< socket pool
TNetItemPool _net_item_pool; ///< net handle pool
static CNetMgr * _instance;
HashList* _ip_hash;
HashList* _session_hash;
TSkBuffMng _udp_pool;
TSkBuffMng _tcp_pool;
TDestPool _dest_ip_pool;
TLinkPool _sock_link_pool;
TNetItemPool _net_item_pool;
};
}
#endif

View File

@ -19,7 +19,6 @@
/**
* @file mt_net_api.h
* @info 线
**/
#ifndef __MT_NET_API_H__
@ -29,90 +28,60 @@
namespace NS_MICRO_THREAD {
/**
* @brief
*/
enum MT_PROTO_TYPE
{
NET_PROTO_UNDEF = 0,
NET_PROTO_UDP = 0x1, ///< 连接类型 UDP
NET_PROTO_TCP = 0x2 ///< 连接类型 TCP
NET_PROTO_UDP = 0x1,
NET_PROTO_TCP = 0x2
};
/**
* @brief
*/
enum MT_RC_TYPE
{
RC_SUCCESS = 0,
RC_ERR_SOCKET = -1, ///< 创建socket失败
RC_SEND_FAIL = -2, ///< 发送失败
RC_RECV_FAIL = -3, ///< 接收失败
RC_CONNECT_FAIL = -4, ///< 连接失败
RC_CHECK_PKG_FAIL = -5, ///< 报文检测失败
RC_NO_MORE_BUFF = -6, ///< 空间超过限制
RC_REMOTE_CLOSED = -7, ///< 后端关闭连接
RC_ERR_SOCKET = -1,
RC_SEND_FAIL = -2,
RC_RECV_FAIL = -3,
RC_CONNECT_FAIL = -4,
RC_CHECK_PKG_FAIL = -5,
RC_NO_MORE_BUFF = -6,
RC_REMOTE_CLOSED = -7,
RC_INVALID_PARAM = -10, ///< 无效参数
RC_INVALID_HANDLER = -11, ///< 无效的句柄
RC_MEM_ERROR = -12, ///< 内存异常
RC_CONFLICT_SID = -13, ///< SESSION ID冲突
RC_KQUEUE_ERROR = -14, ///< rst信号等
RC_INVALID_PARAM = -10,
RC_INVALID_HANDLER = -11,
RC_MEM_ERROR = -12,
RC_CONFLICT_SID = -13,
RC_KQUEUE_ERROR = -14,
};
/**
* @brief , session的回调函数
* @info need_len参数的原因, ,
* ,
* @param data -
* @param len -
* @param session_id -sessionid信息
* @param need_len -buff, 100M
* @return >0 ; =0 , ; <0
*/
typedef int32_t (*CHECK_SESSION_CALLBACK)(const void* data, uint32_t len,
uint64_t* session_id, uint32_t* need_len);
/**
* @brief
*/
class CNetHelper
{
public:
// 转发返回码信息, 按需获取
static char* GetErrMsg(int32_t result);
// 同步收发接口
int32_t SendRecv(void* data, uint32_t len, uint32_t timeout);
// 获取返回buff信息, 有效期直到helper析构
void* GetRspBuff();
// 获取返回包的长度
uint32_t GetRspLen();
// 设置协议的类型, 默认UDP
void SetProtoType(MT_PROTO_TYPE type);
// 设置目的IP地址
void SetDestAddress(struct sockaddr_in* dst);
void SetDestAddress(struct sockaddr_in* dst);
// 设置session本次session id信息, 必须非0
void SetSessionId(uint64_t sid);
void SetSessionId(uint64_t sid);
// 设置session解析回调函数
void SetSessionCallback(CHECK_SESSION_CALLBACK function);
// 构造与虚构
CNetHelper();
~CNetHelper();
private:
void* handler; // 私有句柄, 利于扩展
void* handler;
};

View File

@ -19,7 +19,6 @@
/**
* @file mt_notify.cpp
* @info 线
* @time 20130924
**/
#include <fcntl.h>
@ -39,11 +38,6 @@
using namespace std;
using namespace NS_MICRO_THREAD;
/**
* @brief ,
* @param proxy session模型
*/
void ISessionNtfy::InsertWriteWait(SessionProxy* proxy)
{
if (!proxy->_flag) {
@ -52,10 +46,6 @@ void ISessionNtfy::InsertWriteWait(SessionProxy* proxy)
}
}
/**
* @brief
* @param proxy session模型
*/
void ISessionNtfy::RemoveWriteWait(SessionProxy* proxy)
{
if (proxy->_flag) {
@ -64,10 +54,6 @@ void ISessionNtfy::RemoveWriteWait(SessionProxy* proxy)
}
}
/**
* @brief , 线
* @info UDP可以通知每个线程执行写操作, TCP需要排队写
*/
void UdpSessionNtfy::NotifyWriteWait()
{
MtFrame* frame = MtFrame::Instance();
@ -86,21 +72,15 @@ void UdpSessionNtfy::NotifyWriteWait()
}
}
/**
* @brief socket,
* @return fd的句柄, <0
*/
int UdpSessionNtfy::CreateSocket()
{
// 1. UDP短连接, 每次新创SOCKET
int osfd = socket(AF_INET, SOCK_DGRAM, 0);
if (osfd < 0)
{
MTLOG_ERROR("socket create failed, errno %d(%s)", errno, strerror(errno));
return -1;
}
// 2. 非阻塞设置
int flags = 1;
if (ioctl(osfd, FIONBIO, &flags) < 0)
{
@ -110,7 +90,6 @@ int UdpSessionNtfy::CreateSocket()
return -2;
}
// 可选bind执行, 设置本地port后执行
if (_local_addr.sin_port != 0)
{
int ret = bind(osfd, (struct sockaddr *)&_local_addr, sizeof(_local_addr));
@ -124,7 +103,6 @@ int UdpSessionNtfy::CreateSocket()
}
}
// 3. 更新管理信息, 默认udp session 侦听 epollin
this->SetOsfd(osfd);
this->EnableInput();
MtFrame* frame = MtFrame::Instance();
@ -134,10 +112,6 @@ int UdpSessionNtfy::CreateSocket()
return osfd;
}
/**
* @brief socket,
*/
void UdpSessionNtfy::CloseSocket()
{
int osfd = this->GetOsfd();
@ -152,11 +126,6 @@ void UdpSessionNtfy::CloseSocket()
}
}
/**
* @brief , ,
* @return 0 fd可继续处理其它事件; !=0 fd需跳出回调处理
*/
int UdpSessionNtfy::InputNotify()
{
while (1)
@ -164,7 +133,6 @@ int UdpSessionNtfy::InputNotify()
int ret = 0;
int have_rcv_len = 0;
// 1. 获取收包缓冲区, 优先选择未处理完的链接buff
if (!_msg_buff) {
_msg_buff = MsgBuffPool::Instance()->GetMsgBuf(this->GetMsgBuffSize());
if (NULL == _msg_buff) {
@ -175,7 +143,6 @@ int UdpSessionNtfy::InputNotify()
}
char* buff = (char*)_msg_buff->GetMsgBuff();
// 2. 获取socket, 收包处理
int osfd = this->GetOsfd();
struct sockaddr_in from;
socklen_t fromlen = sizeof(from);
@ -191,13 +158,13 @@ int UdpSessionNtfy::InputNotify()
else
{
MTLOG_ERROR("recv error, fd %d", osfd);
return 0; // 系统错误, UDP 暂不关闭
return 0;
}
}
else if (ret == 0)
{
MTLOG_DEBUG("remote close connection, fd %d", osfd);
return 0; // 对端关闭, UDP 暂不关闭
return 0;
}
else
{
@ -206,7 +173,6 @@ int UdpSessionNtfy::InputNotify()
_msg_buff->SetMsgLen(have_rcv_len);
}
// 3. 检查消息的完整性, 提取sessionid
int sessionid = 0;
ret = this->GetSessionId(buff, have_rcv_len, sessionid);
if (ret <= 0)
@ -218,18 +184,16 @@ int UdpSessionNtfy::InputNotify()
return 0;
}
// 4. 映射查询thread句柄, 连接handle句柄, 设置读事件来临, 挂接msgbuff
ISession* session = SessionMgr::Instance()->FindSession(sessionid);
if (NULL == session)
{
MT_ATTR_API(350403, 1); // session 到达已超时
MT_ATTR_API(350403, 1);
MTLOG_DEBUG("session %d, not find, maybe timeout, drop pkg", sessionid);
MsgBuffPool::Instance()->FreeMsgBuf(_msg_buff);
_msg_buff = NULL;
return 0;
}
// 5. 挂接recvbuff, 唤醒线程
IMtConnection* conn = session->GetSessionConn();
MicroThread* thread = session->GetOwnerThread();
if (!thread || !conn || !conn->GetNtfyObj())
@ -259,43 +223,26 @@ int UdpSessionNtfy::InputNotify()
return 0;
}
/**
* @brief , ,
* @return 0 fd可继续处理其它事件; !=0 fd需跳出回调处理
*/
int UdpSessionNtfy::OutputNotify()
{
NotifyWriteWait();
return 0;
}
/**
* @brief , fd侦听, thread等待处理超时
* @return ,
*/
int UdpSessionNtfy::HangupNotify()
{
// 1. 清理epoll ctl监听事件
MtFrame* frame = MtFrame::Instance();
frame->KqueueCtrlDel(this->GetOsfd(), this->GetEvents());
MTLOG_ERROR("sesson obj %p, recv error event. fd %d", this, this->GetOsfd());
// 2. 重新打开socket
CloseSocket();
// 3. 重加入epoll listen
CreateSocket();
return 0;
}
/**
* @brief epoll侦听事件的回调接口, EPOLLIN, EPOLLOUT
* @param args fd引用对象的指针
* @return 0 , < 0 ,
* @info ,
*/
int UdpSessionNtfy::KqueueCtlAdd(void* args)
{
MtFrame* frame = MtFrame::Instance();
@ -304,7 +251,6 @@ int UdpSessionNtfy::KqueueCtlAdd(void* args)
int osfd = this->GetOsfd();
// 通知对象需要更新, FD通知对象理论上不会复用, 这里做冲突检查, 异常log记录
KqueuerObj* old_obj = fd_ref->GetNotifyObj();
if ((old_obj != NULL) && (old_obj != this))
{
@ -312,7 +258,6 @@ int UdpSessionNtfy::KqueueCtlAdd(void* args)
return -1;
}
// 调用框架的epoll ctl接口, 屏蔽epoll ctrl细节
if (!frame->KqueueCtrlAdd(osfd, KQ_EVENT_WRITE))
{
MTLOG_ERROR("epfd ref add failed, log");
@ -323,11 +268,6 @@ int UdpSessionNtfy::KqueueCtlAdd(void* args)
return 0;
}
/**
* @brief epoll侦听事件的回调接口, EPOLLIN, EPOLLOUT
* @param args fd引用对象的指针
* @return 0 , < 0 ,
*/
int UdpSessionNtfy::KqueueCtlDel(void* args)
{
MtFrame* frame = MtFrame::Instance();
@ -335,8 +275,7 @@ int UdpSessionNtfy::KqueueCtlDel(void* args)
//ASSERT(fd_ref != NULL);
int osfd = this->GetOsfd();
// 通知对象需要更新, FD通知对象理论上不会复用, 这里做冲突检查, 异常log记录
KqueuerObj* old_obj = fd_ref->GetNotifyObj();
if (old_obj != this)
{
@ -344,7 +283,6 @@ int UdpSessionNtfy::KqueueCtlDel(void* args)
return -1;
}
// 调用框架的epoll ctl接口, 屏蔽epoll ctrl细节
if (!frame->KqueueCtrlDel(osfd, KQ_EVENT_WRITE))
{
MTLOG_ERROR("epfd ref del failed, log");
@ -356,41 +294,24 @@ int UdpSessionNtfy::KqueueCtlDel(void* args)
}
/**
* @brief , ,
* @return 0 fd可继续处理其它事件; !=0 fd需跳出回调处理
*/
int TcpKeepNtfy::InputNotify()
{
KeepaliveClose();
return -1;
}
/**
* @brief , ,
* @return 0 fd可继续处理其它事件; !=0 fd需跳出回调处理
*/
int TcpKeepNtfy::OutputNotify()
{
KeepaliveClose();
return -1;
}
/**
* @brief
* @return ,
*/
int TcpKeepNtfy::HangupNotify()
{
KeepaliveClose();
return -1;
}
/**
* @brief
*/
void TcpKeepNtfy::KeepaliveClose()
{
if (_keep_conn) {
@ -400,12 +321,7 @@ void TcpKeepNtfy::KeepaliveClose()
MTLOG_ERROR("_keep_conn ptr null, error");
}
}
/**
* @brief session全局管理句柄
* @return
*/
NtfyObjMgr* NtfyObjMgr::_instance = NULL;
NtfyObjMgr* NtfyObjMgr::Instance (void)
{
@ -417,9 +333,6 @@ NtfyObjMgr* NtfyObjMgr::Instance (void)
return _instance;
}
/**
* @brief session管理全局的销毁接口
*/
void NtfyObjMgr::Destroy()
{
if( _instance != NULL )
@ -429,26 +342,14 @@ void NtfyObjMgr::Destroy()
}
}
/**
* @brief buff的构造函数
*/
NtfyObjMgr::NtfyObjMgr()
{
}
/**
* @brief , ,
*/
NtfyObjMgr::~NtfyObjMgr()
{
}
/**
* @brief session信息
* @param session_name , session封装格式
* @param session ,
* @return 0 , < 0
*/
int NtfyObjMgr::RegisterSession(int session_name, ISessionNtfy* session)
{
if (session_name <= 0 || NULL == session) {
@ -468,11 +369,6 @@ int NtfyObjMgr::RegisterSession(int session_name, ISessionNtfy* session)
return 0;
}
/**
* @brief session信息
* @param session_name , session封装格式
* @return , NULL
*/
ISessionNtfy* NtfyObjMgr::GetNameSession(int session_name)
{
SessionMap::iterator it = _session_map.find(session_name);
@ -486,12 +382,6 @@ ISessionNtfy* NtfyObjMgr::GetNameSession(int session_name)
}
}
/**
* @brief , 线session通知代理对象
* @param type , 线UDP/TCP SESSION通知等
* @param session_name proxy模型,session对象
* @return , NULL
*/
KqueuerObj* NtfyObjMgr::GetNtfyObj(int type, int session_name)
{
KqueuerObj* obj = NULL;
@ -515,7 +405,6 @@ KqueuerObj* NtfyObjMgr::GetNtfyObj(int type, int session_name)
break;
}
// 获取底层的长连接对象, 关联代理与实际的通知对象
if (proxy) {
ISessionNtfy* ntfy = this->GetNameSession(session_name);
if (!ntfy) {
@ -531,10 +420,6 @@ KqueuerObj* NtfyObjMgr::GetNtfyObj(int type, int session_name)
}
/**
* @brief
* @param obj
*/
void NtfyObjMgr::FreeNtfyObj(KqueuerObj* obj)
{
SessionProxy* proxy = NULL;
@ -566,6 +451,3 @@ void NtfyObjMgr::FreeNtfyObj(KqueuerObj* obj)
delete obj;
return;
}

View File

@ -19,7 +19,6 @@
/**
* @file mt_notify.h
* @info 线
* @time 20130926
**/
@ -39,91 +38,43 @@ using std::map;
class SessionProxy;
class TcpKeepConn;
/**
* @brief
*/
enum NTFY_OBJ_TYPE
{
NTFY_OBJ_UNDEF = 0, ///< 未定义的连接对象
NTFY_OBJ_THREAD = 1, ///< 短连接对象, 一个fd对应一个thread
NTFY_OBJ_KEEPALIVE = 2, ///< TCP心跳保持的notify对象, 不关联 thread
NTFY_OBJ_SESSION = 3, ///< UDP的session模型, 代理的长连接对象
NTFY_OBJ_UNDEF = 0,
NTFY_OBJ_THREAD = 1,
NTFY_OBJ_KEEPALIVE = 2,
NTFY_OBJ_SESSION = 3,
};
/**
* @brief
*/
enum MULTI_PROTO
{
MT_UNKNOWN = 0,
MT_UDP = 0x1, ///< 连接类型 UDP
MT_TCP = 0x2 ///< 连接类型 TCP
MT_UDP = 0x1,
MT_TCP = 0x2
};
/**
* @brief session模型,
*/
typedef TAILQ_ENTRY(SessionProxy) NtfyEntry;
typedef TAILQ_HEAD(__NtfyList, SessionProxy) NtfyList;
class ISessionNtfy : public KqueuerObj
{
public:
/**
* @brief , sessionid信息
* @param pkg
* @param len
* @param session sessionid,
* @return <=0 , >0
*/
virtual int GetSessionId(void* pkg, int len, int& session) { return 0;};
/**
* @brief socket,
* @return fd的句柄, <0
*/
virtual int CreateSocket(){return -1;};
/**
* @brief socket,
*/
virtual void CloseSocket(){};
/**
* @brief , ,
* @return 0 fd可继续处理其它事件; !=0 fd需跳出回调处理
*/
virtual int InputNotify(){return 0;};
/**
* @brief , ,
* @return 0 fd可继续处理其它事件; !=0 fd需跳出回调处理
*/
virtual int OutputNotify(){return 0;};
/**
* @brief
* @return ,
*/
virtual int HangupNotify(){return 0;};
/**
* @brief epoll侦听事件的回调接口, EPOLLIN, EPOLLOUT
* @param args fd引用对象的指针
* @return 0 , < 0 ,
*/
virtual int KqueueCtlAdd(void* args){return 0;};
/**
* @brief epoll侦听事件的回调接口, EPOLLIN, EPOLLOUT
* @param args fd引用对象的指针
* @return 0 , < 0 ,
*/
virtual int KqueueCtlDel(void* args){return 0;};
/**
* @brief
*/
ISessionNtfy(): KqueuerObj(0) {
_proto = MT_UDP;
_buff_size = 0;
@ -132,85 +83,46 @@ public:
}
virtual ~ISessionNtfy() { };
/**
* @brief proto信息
*/
void SetProtoType(MULTI_PROTO proto) {
_proto = proto;
};
/**
* @brief proto信息
* @return proto type
*/
MULTI_PROTO GetProtoType() {
return _proto;
};
/**
* @brief buff大小, 使msgbuff队列
* @return 0
*/
void SetMsgBuffSize(int buff_size) {
_buff_size = buff_size;
};
/**
* @brief buff大小, , 65535
* @return buff最大长度
*/
int GetMsgBuffSize() {
return (_buff_size > 0) ? _buff_size : 65535;
}
/**
* @brief
*/
void InsertWriteWait(SessionProxy* proxy);
/**
* @brief
*/
void RemoveWriteWait(SessionProxy* proxy);
/**
* @brief , 线
* @info UDP可以通知每个线程执行写操作, TCP需要排队写
*/
virtual void NotifyWriteWait(){};
protected:
MULTI_PROTO _proto; // 协议类型 UDP/TCP
int _buff_size; // 最大消息长度
NtfyList _write_list; // 可写等待队列
MtMsgBuf* _msg_buff; // 临时收包存放缓冲区
MULTI_PROTO _proto;
int _buff_size;
NtfyList _write_list;
MtMsgBuf* _msg_buff;
};
/**
* @brief UDP长连接session模型的基类接口
* @info session需要继承该接口, , GetSessionId函数
* @info ,
*/
class UdpSessionNtfy : public ISessionNtfy
{
public:
/**
* @brief , sessionid信息,
* @param pkg
* @param len
* @param session sessionid,
* @return <=0 , >0
*/
virtual int GetSessionId(void* pkg, int len, int& session) { return 0;};
public:
/**
* @brief
*/
UdpSessionNtfy() : ISessionNtfy(){
ISessionNtfy::SetProtoType(MT_UDP);
@ -220,61 +132,24 @@ public:
}
virtual ~UdpSessionNtfy() { };
/**
* @brief , 线
* @info UDP可以通知每个线程执行写操作, TCP需要排队写
*/
virtual void NotifyWriteWait();
/**
* @brief socket,
* @return fd的句柄, <0
*/
virtual int CreateSocket();
/**
* @brief socket,
*/
virtual void CloseSocket();
/**
* @brief , ,
* @return 0 fd可继续处理其它事件; !=0 fd需跳出回调处理
*/
virtual int InputNotify();
/**
* @brief , ,
* @return 0 fd可继续处理其它事件; !=0 fd需跳出回调处理
*/
virtual int OutputNotify();
/**
* @brief
* @return ,
*/
virtual int HangupNotify();
/**
* @brief epoll侦听事件的回调接口, EPOLLIN, EPOLLOUT
* @param args fd引用对象的指针
* @return 0 , < 0 ,
*/
virtual int KqueueCtlAdd(void* args);
/**
* @brief epoll侦听事件的回调接口, EPOLLIN, EPOLLOUT
* @param args fd引用对象的指针
* @return 0 , < 0 ,
*/
virtual int KqueueCtlDel(void* args);
public:
/**
* @brief udp本地的本地bind地址, bind会冲突,
* , port可使用
*/
void SetLocalAddr(struct sockaddr_in* local_addr) {
memcpy(&_local_addr, local_addr, sizeof(_local_addr));
};
@ -285,47 +160,28 @@ protected:
};
/**
* @brief UDP模式session模型的代理通知对象, session notify
* @info session proxy epoll注册, ,
*/
class SessionProxy : public KqueuerObj
{
public:
int _flag; ///< 0-不在队列中, 1-在等待队列
NtfyEntry _write_entry; ///< 关联可写等待队列的管理入口
int _flag;
NtfyEntry _write_entry;
/**
* @brief , fd句柄
*/
void SetRealNtfyObj(ISessionNtfy* obj) {
_real_ntfy = obj;
this->SetOsfd(obj->GetOsfd());
};
/**
* @brief
*/
ISessionNtfy* GetRealNtfyObj() {
return _real_ntfy;
};
public:
/**
* @brief ,
*/
virtual void Reset() {
_real_ntfy = NULL;
this->KqueuerObj::Reset();
};
/**
* @brief epoll侦听事件的回调接口, EPOLLIN, EPOLLOUT
* @param args fd引用对象的指针
* @return 0 , < 0 ,
*/
virtual int KqueueCtlAdd(void* args) {
if (!_real_ntfy) {
return -1;
@ -344,11 +200,6 @@ public:
return 0;
};
/**
* @brief epoll侦听事件的回调接口, EPOLLIN, EPOLLOUT
* @param args fd引用对象的指针
* @return 0 , < 0 ,
*/
virtual int KqueueCtlDel(void* args) {
if (!_real_ntfy) {
return -1;
@ -364,86 +215,48 @@ public:
};
private:
ISessionNtfy* _real_ntfy; // 实际的执行者
ISessionNtfy* _real_ntfy;
};
/**
* @brief TCP模式的keepalive通知对象, ,
*/
class TcpKeepNtfy: public KqueuerObj
{
public:
/**
* @brief
*/
TcpKeepNtfy() : _keep_conn(NULL){};
/**
* @brief , ,
* @return 0 fd可继续处理其它事件; !=0 fd需跳出回调处理
*/
virtual int InputNotify();
/**
* @brief , ,
* @return 0 fd可继续处理其它事件; !=0 fd需跳出回调处理
*/
virtual int OutputNotify();
/**
* @brief
* @return ,
*/
virtual int HangupNotify();
/**
* @brief
*/
void SetKeepNtfyObj(TcpKeepConn* obj) {
_keep_conn = obj;
};
/**
* @brief
*/
TcpKeepConn* GetKeepNtfyObj() {
return _keep_conn;
};
/**
* @brief
*/
void KeepaliveClose();
private:
TcpKeepConn* _keep_conn; // 实际的连接器对象
TcpKeepConn* _keep_conn;
};
/**
* @brief , new/delete的对象操作,
*/
template<typename ValueType>
class CPtrPool
{
public:
typedef typename std::queue<ValueType*> PtrQueue; ///< 内存指针队列
typedef typename std::queue<ValueType*> PtrQueue;
public:
/**
* @brief
* @param max , 500
*/
explicit CPtrPool(int max = 500) : _max_free(max), _total(0){};
/**
* @brief , freelist
*/
~CPtrPool() {
ValueType* ptr = NULL;
while (!_ptr_list.empty()) {
@ -453,10 +266,6 @@ public:
}
};
/**
* @brief , , new
* @return ,
*/
ValueType* AllocPtr() {
ValueType* ptr = NULL;
if (!_ptr_list.empty()) {
@ -470,9 +279,6 @@ public:
return ptr;
};
/**
* @brief , , ,
*/
void FreePtr(ValueType* ptr) {
if ((int)_ptr_list.size() >= _max_free) {
delete ptr;
@ -483,15 +289,11 @@ public:
};
protected:
PtrQueue _ptr_list; ///< 空闲队列
int _max_free; ///< 最大空闲元素
int _total; ///< 所有new的对象个数统计
PtrQueue _ptr_list;
int _max_free;
int _total;
};
/**
* @brief
*/
class NtfyObjMgr
{
public:
@ -499,70 +301,31 @@ public:
typedef std::map<int, ISessionNtfy*> SessionMap;
typedef CPtrPool<KqueuerObj> NtfyThreadQueue;
typedef CPtrPool<SessionProxy> NtfySessionQueue;
/**
* @brief
* @return
*/
static NtfyObjMgr* Instance (void);
/**
* @brief
*/
static void Destroy(void);
/**
* @brief session信息
* @param session_name , session封装格式
* @param session ,
* @return 0 , < 0
*/
int RegisterSession(int session_name, ISessionNtfy* session);
/**
* @brief session信息
* @param session_name , session封装格式
* @return , NULL
*/
ISessionNtfy* GetNameSession(int session_name);
/**
* @brief , 线session通知代理对象
* @param type , 线UDP/TCP SESSION通知等
* @param session_name proxy模型,session对象
* @return , NULL
*/
KqueuerObj* GetNtfyObj(int type, int session_name = 0);
/**
* @brief
* @param obj
*/
void FreeNtfyObj(KqueuerObj* obj);
/**
* @brief
*/
~NtfyObjMgr();
private:
/**
* @brief buff的构造函数
*/
NtfyObjMgr();
static NtfyObjMgr * _instance; ///< 单例类句柄
SessionMap _session_map; ///< 全局的注册session管理
NtfyThreadQueue _fd_ntfy_pool; ///< fd通知对象
NtfySessionQueue _udp_proxy_pool; ///< fd通知对象
static NtfyObjMgr * _instance;
SessionMap _session_map;
NtfyThreadQueue _fd_ntfy_pool;
NtfySessionQueue _udp_proxy_pool;
};
}
#endif

View File

@ -1,251 +0,0 @@
/**
* 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.
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <time.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "mt_incl.h"
#include "micro_thread.h"
using namespace NS_MICRO_THREAD;
static bool run = true;
static struct sockaddr_in addr;
int mt_tcp_create_sock(void)
{
int fd;
//int flag;
// ´´½¨socket
fd = socket(AF_INET, SOCK_STREAM, 0);
if (fd < 0)
{
printf("create tcp socket failed, error: %m\n");
return -1;
}
// ÉèÖÃsocket·Ç×èÈû
/*
flag = fcntl(fd, F_GETFL, 0);
if (flag == -1)
{
::close(fd);
printf("get fd flags failed, error: %m\n");
return -2;
}
if (flag & O_NONBLOCK)
return fd;
if (fcntl(fd, F_SETFL, flag | O_NONBLOCK | O_NDELAY) == -1)
{
::close(fd);
printf("set fd flags failed, error: %m\n");
return -3;
}
*/
int nb = 1;
ioctl(fd, FIONBIO, &nb);
return fd;
}
void echo(void* arg)
{
char buf[1024];
int ret = 0;
int *p = (int *)arg;
int clt_fd = *p;
printf("start to echo with client: %d\n", clt_fd);
while (1) {
ret = mt_recv(clt_fd, (void*)buf,1024,0,-1);
if(ret<0)
{
printf("recv client data failed[%m]\n");
mt_sleep(1);
break;
}
ret = mt_send(clt_fd, (void*)buf, ret, 0, 1000);
if (ret < 0) {
printf("send client data failed[%m]\n");
mt_sleep(1);
break;
}
}
if(clt_fd>0) close(clt_fd);
delete p;
}
void server(void* arg)
{
int fd = mt_tcp_create_sock();
if(fd<0)
{
run = false;
printf("create listen socket failed\n");
return;
}
int optval = 1;
unsigned optlen = sizeof(optval);
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &optval, optlen);
if (bind(fd, (struct sockaddr*)&addr, sizeof(addr)) < 0)
{
close(fd);
printf("bind failed [%m]\n");
return ;
}
if (listen(fd, 1024) < 0)
{
close(fd);
printf("listen failed[%m]\n");
return ;
}
int clt_fd = 0;
int *p;
while(run)
{
struct sockaddr_in client_addr;
int addr_len = sizeof(client_addr);;
clt_fd = mt_accept(fd, (struct sockaddr*)&client_addr, (socklen_t*)&addr_len, -1);
if(clt_fd<0)
{
mt_sleep(1);
continue;
}
int nb = 1;
ioctl(clt_fd, FIONBIO, &nb);
p = new int(clt_fd);
printf("start a new micro thread to echo with client: %d\n", clt_fd);
mt_start_thread((void*)echo, (void *)p);
mt_sleep(1);
}
printf("server exit\n");
}
struct MsgCtx
{
int check_count;
int msg_id;
};
int TcpMsgChecker(void* buf, int len, bool closed, void* msg_ctx, bool& msg_len_detected)
{
struct MsgCtx* ctx = (struct MsgCtx*)msg_ctx;
ctx->check_count++;
printf("#%d msg check msg times #%d, buf=%p, len=%d, closed=%d\n", ctx->msg_id, ctx->check_count, buf,len,closed);
if(len<4)
{
return 0;
}
int r_len=ntohl(*(uint32_t*)buf);
//if(r_len!=len)
// {
// return 0;
//}
msg_len_detected = true;
return r_len;
}
/*
void client(void* arg)
{
//char buf[1024];
struct MsgCtx ctx;
void* rcv_buf = NULL;
int rcv_len = 0;
bool keep_rcv_buf = true;
int ret = 0;
char snd_ch = 1;
int count=0;
while(true)
{
rcv_buf = NULL;
rcv_len = 1;
keep_rcv_buf = (((++count)%2) == 0);
ctx.check_count = 0;
ctx.msg_id = count;
ret = mt_tcpsendrcv_ex((struct sockaddr_in*)&addr, (void*)&snd_ch, 1, rcv_buf, rcv_len,20000, &TcpMsgChecker, (void*)&ctx, MT_TCP_SHORT,keep_rcv_buf);
if(ret<0)
{
printf("client send rcv failed[%m]\n");
continue;
}
printf("#%d client tcp finished: rcv_len=%d, rcv_buf=%p, keep_rcv_buf=%d\n",count, rcv_len, rcv_buf,keep_rcv_buf);
if(keep_rcv_buf)
{
if(rcv_buf==NULL)
{
printf("client should hold rcvbuf, something wrong\n");
continue;
}
free(rcv_buf);
}
}
printf("client exit!");
}
*/
int main(int argc, char* argv[])
{
memset((void*)&addr,0,sizeof(addr));
addr.sin_family=AF_INET;
addr.sin_addr.s_addr = inet_addr("112.90.143.29");
addr.sin_port = htons(19999);
mt_init_frame(argc, argv);
mt_start_thread((void*)server,NULL);
while (run) {
mt_sleep(10);
}
printf("main exit");
}

View File

@ -19,7 +19,6 @@
/**
* @file mt_session.cpp
* @info 线
* @time 20130924
**/
@ -29,23 +28,15 @@
using namespace std;
using namespace NS_MICRO_THREAD;
/**
* @brief session接口资源自回收处理
*/
ISession::~ISession()
{
if (_session_flg) {
SessionMgr* sessionmgr = SessionMgr::Instance();
sessionmgr->RemoveSession(_session_id);
_session_flg = (int)SESSION_IDLE; // 额外处理, 在remove函数内处理会加大开销
_session_flg = (int)SESSION_IDLE;
}
}
/**
* @brief session全局管理句柄
* @return
*/
SessionMgr* SessionMgr::_instance = NULL;
SessionMgr* SessionMgr::Instance (void)
{
@ -57,9 +48,6 @@ SessionMgr* SessionMgr::Instance (void)
return _instance;
}
/**
* @brief session管理全局的销毁接口
*/
void SessionMgr::Destroy()
{
if( _instance != NULL )
@ -69,18 +57,12 @@ void SessionMgr::Destroy()
}
}
/**
* @brief buff的构造函数
*/
SessionMgr::SessionMgr()
{
_curr_session = 0;
_hash_map = new HashList(100000);
}
/**
* @brief , ,
*/
SessionMgr::~SessionMgr()
{
if (_hash_map) {
@ -89,9 +71,6 @@ SessionMgr::~SessionMgr()
}
}
/**
* @brief Session数据存储
*/
int SessionMgr::InsertSession(ISession* session)
{
if (!_hash_map || !session) {
@ -109,9 +88,6 @@ int SessionMgr::InsertSession(ISession* session)
return _hash_map->HashInsert(session);
}
/**
* @brief session数据
*/
ISession* SessionMgr::FindSession(int session_id)
{
if (!_hash_map) {
@ -124,9 +100,6 @@ ISession* SessionMgr::FindSession(int session_id)
return dynamic_cast<ISession*>(_hash_map->HashFind(&key));
}
/**
* @brief session数据
*/
void SessionMgr::RemoveSession(int session_id)
{
if (!_hash_map) {
@ -138,5 +111,3 @@ void SessionMgr::RemoveSession(int session_id)
key.SetSessionId(session_id);
return _hash_map->HashRemove(&key);
}

View File

@ -19,7 +19,6 @@
/**
* @file mt_session.h
* @info 线, session信息
* @time 20130924
**/
@ -35,28 +34,19 @@ class IMtConnection;
enum SESSION_FLAG
{
SESSION_IDLE = 0, ///< SESSION 未加入hash管理
SESSION_INUSE = 1, ///< SESSION 进入管理状态
SESSION_IDLE = 0,
SESSION_INUSE = 1,
};
/**
* @brief session接口定义, session可映射出thread,action等
*/
class ISession : public HashKey
{
public:
/**
* @brief
*/
ISession() : _session_id(0), _session_flg(0), _thread(NULL), _connection(NULL) {};
virtual ~ISession();
public:
/**
* @brief ID的设置与获取
*/
void SetSessionId(int id) {
_session_id = id;
};
@ -64,9 +54,6 @@ public:
return _session_id;
};
/**
* @brief 线
*/
MicroThread* GetOwnerThread(){
return _thread;
};
@ -74,9 +61,6 @@ public:
_thread = thread;
};
/**
* @brief
*/
IMtConnection* GetSessionConn(){
return _connection;
};
@ -84,9 +68,6 @@ public:
_connection = conn;
};
/**
* @brief flag的设置与获取
*/
void SetSessionFlag(int flag) {
_session_flg = flag;
};
@ -94,52 +75,30 @@ public:
return _session_flg;
};
/**
* @brief hash算法, key的hash值
* @return hash值
*/
virtual uint32_t HashValue(){
return _session_id;
};
/**
* @brief cmp方法, ID下, key比较
* @return hash值
*/
virtual int HashCmp(HashKey* rhs){
return this->_session_id - (int)rhs->HashValue();
};
protected:
int _session_id; // 会话id信息
int _session_flg; // 记录session状态 0 -不在hash中, 1 -hash管理中
MicroThread* _thread; // 会话所属的session
IMtConnection* _connection; // 会话关联的连接
int _session_id;
int _session_flg;
MicroThread* _thread;
IMtConnection* _connection;
};
/**
* @brief session管理结构
*/
class SessionMgr
{
public:
/**
* @brief
* @return
*/
static SessionMgr* Instance (void);
/**
* @brief
*/
static void Destroy();
/**
* @brief sessionid
* @return
*/
int GetSessionId(void) {
_curr_session++;
if (!_curr_session) {
@ -148,40 +107,23 @@ public:
return _curr_session;
};
/**
* @brief Session数据存储
*/
int InsertSession(ISession* session);
/**
* @brief session数据
*/
ISession* FindSession(int session_id);
/**
* @brief session数据
*/
void RemoveSession(int session_id);
/**
* @brief
*/
~SessionMgr();
private:
/**
* @brief buff的构造函数
*/
SessionMgr();
static SessionMgr * _instance; ///< 单例类句柄
int _curr_session; ///< session种子
HashList* _hash_map; ///< 按sessionid hash存储
static SessionMgr * _instance;
int _curr_session;
HashList* _hash_map;
};
}
#endif

View File

@ -19,8 +19,6 @@
/**
* @filename mt_sys_hook.cpp
* @info 线hook系统api, ,
* hook socket相关的API, HOOK , pth与libco实现
*/
#include <stdio.h>
@ -44,25 +42,18 @@ using namespace NS_MICRO_THREAD;
#define MT_FD_FLG_INUSE 0x1
#define MT_FD_FLG_UNBLOCK 0x2
/**
* @brief sockt分配一个管理结构, HOOK,
*/
typedef struct socket_hook_info
{
int sock_flag; // 是否使用HOOK, 是否用户设置UNBLOCK
int read_timeout; // socket读取超时时间, ms单位
int write_timeout; // socket写入超时时间, ms单位
int sock_flag;
int read_timeout;
int write_timeout;
}MtHookFd;
MtSyscallFuncTab g_mt_syscall_tab; // 全局符号表
int g_mt_hook_flag; // 全局控制标记
int g_ff_hook_flag; // 全局控制标记
static MtHookFd g_mt_hook_fd_tab[MT_HOOK_MAX_FD]; // 全局fd管理
MtSyscallFuncTab g_mt_syscall_tab;
int g_mt_hook_flag;
int g_ff_hook_flag;
static MtHookFd g_mt_hook_fd_tab[MT_HOOK_MAX_FD];
/**
* @brief , hook fd相关的信息, socket hook, open no hook
*/
MtHookFd* mt_hook_find_fd(int fd)
{
if ((fd < 0) || (fd >= MT_HOOK_MAX_FD)) {
@ -77,9 +68,6 @@ MtHookFd* mt_hook_find_fd(int fd)
}
}
/**
* @brief , socket设置hook, socket, IO
*/
void mt_hook_new_fd(int fd)
{
if ((fd < 0) || (fd >= MT_HOOK_MAX_FD)) {
@ -92,9 +80,6 @@ void mt_hook_new_fd(int fd)
fd_info->write_timeout = 500;
}
/**
* @brief , hook socket
*/
void mt_hook_free_fd(int fd)
{
if ((fd < 0) || (fd >= MT_HOOK_MAX_FD)) {
@ -107,9 +92,6 @@ void mt_hook_free_fd(int fd)
fd_info->write_timeout = 0;
}
/**
* @brief HOOK接口, mt库后, api,
*/
#ifdef __cplusplus
extern "C" {
#endif
@ -135,17 +117,14 @@ int ioctl(int fd, unsigned long cmd, ...)
}
}
return ff_hook_ioctl(fd, cmd, arg);
return ff_hook_ioctl(fd, cmd, arg);
}
/**
* @brief HOOK接口, mt库后, api, unblock
*/
int socket(int domain, int type, int protocol)
{
mt_hook_syscall(socket);
if (!ff_hook_active())
if (!ff_hook_active())
{
return mt_real_func(socket)(domain, type, protocol);
}
@ -159,36 +138,29 @@ int socket(int domain, int type, int protocol)
mt_hook_new_fd(fd);
mt_hook_syscall(ioctl);
int nb = 1;
ff_hook_ioctl(fd, FIONBIO, &nb);
int nb = 1;
ff_hook_ioctl(fd, FIONBIO, &nb);
return fd;
}
/**
* @brief HOOK接口, mt库后, api
*/
int close(int fd)
{
mt_hook_syscall(close);
if (!ff_hook_active())
if (!ff_hook_active())
{
return mt_real_func(close)(fd);
}
mt_hook_free_fd(fd);
return ff_hook_close(fd);
return ff_hook_close(fd);
}
/**
* @brief HOOK接口, mt库后, api
*/
int connect(int fd, const struct sockaddr *address, socklen_t address_len)
{
mt_hook_syscall(connect);
MtHookFd* hook_fd = mt_hook_find_fd(fd);
if (!mt_hook_active() || !hook_fd || !ff_hook_active())
if (!mt_hook_active() || !hook_fd || !ff_hook_active())
{
return mt_real_func(connect)(fd, address, address_len);
}
@ -201,9 +173,6 @@ int connect(int fd, const struct sockaddr *address, socklen_t address_len)
return MtFrame::connect(fd, address, (int)address_len, hook_fd->write_timeout);
}
/**
* @brief HOOK接口, mt库后, api, unblock,
*/
ssize_t read(int fd, void *buf, size_t nbyte)
{
mt_hook_syscall(read);
@ -221,9 +190,6 @@ ssize_t read(int fd, void *buf, size_t nbyte)
return MtFrame::read(fd, buf, nbyte, hook_fd->read_timeout);
}
/**
* @brief HOOK接口, mt库后, api, unblock,
*/
ssize_t write(int fd, const void *buf, size_t nbyte)
{
mt_hook_syscall(write);
@ -241,9 +207,6 @@ ssize_t write(int fd, const void *buf, size_t nbyte)
return MtFrame::write(fd, buf, nbyte, hook_fd->write_timeout);
}
/**
* @brief HOOK接口, mt库后, api, unblock,
*/
ssize_t sendto(int fd, const void *message, size_t length, int flags,
const struct sockaddr *dest_addr, socklen_t dest_len)
{
@ -263,9 +226,6 @@ ssize_t sendto(int fd, const void *message, size_t length, int flags,
dest_addr, dest_len, hook_fd->write_timeout);
}
/**
* @brief HOOK接口, mt库后, api, unblock,
*/
ssize_t recvfrom(int fd, void *buffer, size_t length, int flags,
struct sockaddr *address, socklen_t *address_len)
{
@ -285,9 +245,6 @@ ssize_t recvfrom(int fd, void *buffer, size_t length, int flags,
}
/**
* @brief HOOK接口, mt库后, api, unblock,
*/
ssize_t recv(int fd, void *buffer, size_t length, int flags)
{
mt_hook_syscall(recv);
@ -305,9 +262,6 @@ ssize_t recv(int fd, void *buffer, size_t length, int flags)
return MtFrame::recv(fd, buffer, length, flags, hook_fd->read_timeout);
}
/**
* @brief HOOK接口, mt库后, api, unblock,
*/
ssize_t send(int fd, const void *buf, size_t nbyte, int flags)
{
mt_hook_syscall(send);
@ -325,10 +279,6 @@ ssize_t send(int fd, const void *buf, size_t nbyte, int flags)
return MtFrame::send(fd, buf, nbyte, flags, hook_fd->write_timeout);
}
/**
* @brief HOOK接口, mt库后, api,
*/
int setsockopt(int fd, int level, int option_name, const void *option_value, socklen_t option_len)
{
mt_hook_syscall(setsockopt);
@ -351,14 +301,9 @@ int setsockopt(int fd, int level, int option_name, const void *option_value, soc
}
}
return ff_hook_setsockopt(fd, level, option_name, option_value, option_len);
return ff_hook_setsockopt(fd, level, option_name, option_value, option_len);
}
/**
* @brief HOOK接口, mt库后, api,
*/
int fcntl(int fd, int cmd, ...)
{
va_list ap;
@ -388,7 +333,6 @@ int fcntl(int fd, int cmd, ...)
return ff_hook_fcntl(fd, cmd, arg);
}
int listen(int sockfd, int backlog)
{
mt_hook_syscall(listen);
@ -397,7 +341,7 @@ int listen(int sockfd, int backlog)
return mt_real_func(listen)(sockfd, backlog);
}
return ff_hook_listen(sockfd, backlog);
return ff_hook_listen(sockfd, backlog);
}
int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
@ -408,7 +352,7 @@ int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
return mt_real_func(bind)(sockfd, addr, addrlen);
}
return ff_hook_bind(sockfd, addr, addrlen);
return ff_hook_bind(sockfd, addr, addrlen);
}
int accept(int fd, struct sockaddr *addr, socklen_t *addrlen)
@ -419,7 +363,7 @@ int accept(int fd, struct sockaddr *addr, socklen_t *addrlen)
return mt_real_func(accept)(fd, addr, addrlen);
}
return ff_hook_accept(fd, addr, addrlen);
return ff_hook_accept(fd, addr, addrlen);
}
#ifdef __cplusplus

View File

@ -19,8 +19,6 @@
/**
* @filename mt_sys_hook.h
* @info 线hook系统api, ,
* HOOK , pth与libco实现
*/
#ifndef _MT_SYS_HOOK___
@ -35,10 +33,6 @@
extern "C" {
#endif
/******************************************************************************/
/* 1. HOOK 的函数定义部分 */
/******************************************************************************/
typedef int (*func_socket)(int domain, int type, int protocol);
typedef int (*func_bind)(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
typedef int (*func_listen)(int sockfd, int backlog);
@ -63,14 +57,6 @@ typedef int (*func_fcntl)(int fd, int cmd, ...);
typedef unsigned int (*func_sleep)(unsigned int seconds);
/******************************************************************************/
/* 2. 全局的hook函数结构 */
/******************************************************************************/
/**
* @brief Hook的原始函数集中管理定义,
*/
typedef struct mt_syscall_func_tab
{
func_socket real_socket;
@ -88,25 +74,21 @@ typedef struct mt_syscall_func_tab
func_fcntl real_fcntl;
func_ioctl real_ioctl;
func_sleep real_sleep; // 暂不支持因为没有与fd关联, 防止滥用
func_select real_select; // 暂不支持, 1024限制问题
func_poll real_poll; // 暂不支持, 确认需求后实施
func_sleep real_sleep;
func_select real_select;
func_poll real_poll;
func_accept real_accept;
}MtSyscallFuncTab;
} MtSyscallFuncTab;
/******************************************************************************/
/* 3. 直接调用原始系统api的接口 */
/******************************************************************************/
extern MtSyscallFuncTab g_mt_syscall_tab; // 全局符号表
extern int g_mt_hook_flag; // 全局控制标记
extern int g_ff_hook_flag; // 全局控制标记
extern MtSyscallFuncTab g_mt_syscall_tab;
extern int g_mt_hook_flag;
extern int g_ff_hook_flag;
#define mt_hook_syscall(name) \
do { \
if (!g_mt_syscall_tab.real_##name) { \
g_mt_syscall_tab.real_##name = (func_##name)dlsym(RTLD_NEXT, #name);\
g_mt_syscall_tab.real_##name = (func_##name)dlsym(RTLD_NEXT, #name);\
} \
} while (0)

View File

@ -17,17 +17,6 @@
*/
/**
* @file mt_version.h
* @info 线
* @time 20131018
* ------------------------------------------------------------------------
* @brief v0.2.0 - UDP按session模式映射上下文
* v0.2.1 - TCP的sendrcv接口
* v0.2.3 -
* v0.2.4 - TCP的sendrcv接口动态扩展接收buf
*/
#ifndef _MT_VERSION_EX__
#define _MT_VERSION_EX__