Sylar Hook模块的实现

这篇博客详细介绍了如何实现一个模板化的socket操作函数hook,它包含对文件描述符的操作,处理超时和非阻塞情况。在执行原始方法时,如果遇到系统中断会重试,而当遇到阻塞时,会使用定时器进行超时控制,并在超时时取消事件。整个过程涉及到事件的添加、定时器管理和协程的调度。
摘要由CSDN通过智能技术生成

 主要是do_io(文件描述符的操作)注释,有些函数简写了

//实现socket操作函数的hook封装
template<typename OriginFun,typename ... Args>
ssize_t do_io(int fd, OriginFun cb, const char* hook_fun_name, uint32_t event, int timeout_so, Args&&... args) {
    if (!is_hook_flag) {
        return cb(fd, std::forward<Args>(args)...);
    }
    //Dlib::Fdctx::ptr ctx=  //通过Fdmanager获得fdctx
    Fdctx::ptr ctx;
    if (!ctx) {
        return cb(fd, std::forward<Args>(args)...);
    }
    if (ctx->isClose()) {
        errno = EBADF;   //出错
        return -1;
    }
    if (!ctx->isSocket() || ctx->getUserNonblock()) {  //不是socket或设置了非阻塞
        return cb(fd, std::forward<Args>(args)...);
    }
    uint64_t to = ctx->getTimeout(timeout_so);    //超时时间
    std::shared_ptr<timer_info> tinfo(new timer_info);     //超时的条件
retry:
    size_t n = cb(fd, std::forward<Args>(args)...);  //执行原始方法,因为是非阻塞的,所以马上返回结果
    while (n==-1&&errno==EINTR)  //如果是被系统中断,程序执行
    {
        size_t n = cb(fd, std::forward<Args>(args)...);
    }
    if (n == -1 && errno == EAGAIN) {  //阻塞状态,阻塞的等待资源上,就手动
        auto Io = Mainf->m_poll;
        Timer::ptr timer;
        std::weak_ptr<timer_info> winfo(timer_info);
        if (to != (uint64_t)-1) {//如果有超时时间,添加条件的超时定时器(拿这个条件唤醒以下,如果条件没错(已经超时了)设置成错误,并取消事件)
            timer = Io->add; //添加定时器{
            //这是定时器的回调函数
            auto t = winfo.lock();
            if (!t || t->cancelled) {  //说明没有触发定时器
                return;
            }
            t->cancelled = ETIMEDOUT;
            io->cancel();//取消事件,将他唤醒
        }
        //添加事件
        int c = 0;  //计数器,计算重试了多少次,
        uint64_t now = 0;
        //添加一个事件
        int rt = io->addEvent;  
        if (rt) {  //加事件失败
            if (timer) { //取消定时器
                timer->cancel;
            }
            return -1;
        }
        else {  //加事件成功,yield出去
            yiedl();
            //唤醒了,因为我的协程上下文此时保存在这,所以resume的时候,从这开始执行(从这开始唤醒)
            //有两个唤醒时机:一个是定时器返回,一个是需要的资源来到
            if (timer) { //如果timer还存在
                timer->cancel(); 
            }
            if (timer_info->canceled) {  //说明定时任务把他唤醒了
                errno = timer_info->cancelled;
                return -1;
            }
            //有Io事件回来了,要重新尝试一次执行函数
            goto retry;
        }

    }
        
    return n;

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

blackhawknoe

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值