libuv学习笔记(3)

libuv学习笔记(3)

uv_handle_t结构体以及相关函数

结构体定义

typedef struct uv_handle_s uv_handle_t;
struct uv_handle_s {
    UV_HANDLE_FIELDS
};

libuv将许多通用的数据结构定义为宏,这样类型之间的关系就很清晰,并且能够实现类似继承的关系。
UV_HANDLE_FIELDS宏定义如下(其他所有类型的handle都包含本宏,所以能够转换为uv_handle_t):

#define UV_HANDLE_FIELDS                
   /* 公有数据,指向用户自定义数据,libuv不使用该成员*/                  \
   void* data;                                                              \
   /* 只读数据 */                                                           \
   uv_loop_t* loop;  //指向依赖的循环
   uv_handle_type type; //句柄类型                                      \
   /* 内部使用数据*/                                                        \
   uv_close_cb close_cb; //句柄关闭时的回调函数                             \
   void* handle_queue[2];//句柄队列指针,分别指向上一个和下一个             \
   union {                                                                  \
     int fd;                                                                \
     void* reserved[4];                                                     \
   } u;                                                                     \
   UV_HANDLE_PRIVATE_FIELDS//内部使用数据宏定义                          \


UV_HANDLE_PRIVATE_FIELDS宏定义如下:

#define UV_HANDLE_PRIVATE_FIELDS                                         \
   uv_handle_t* endgame_next;//指向下一个需要关闭的handle                   \
   unsigned int flags;//状态标记,比如引用、关闭、正在关闭、激活等状态

相关函数

判断handle是否是激活(active)状态 导出函数,在uv.h中定义,handle.c中实现
int  uv_is_active(const uv_handle_t*  handle)
{
    //handle是激活状态且非正在关闭状态
    return (handle->flags & UV_HANDLE_ACTIVE) &&
         !(handle->flags & UV_HANDLE_CLOSING);
}
判断handle是否是关闭状态 导出函数,在uv.h中定义,handle.c中实现
int uv_is_closing(const uv_handle_t* handle)
{
    //flags可以是UV__HANDLE_CLOSING或UV_HANDLE_CLOSED
    //双重否定将返回值强制转换为bool,然后转换为int
    return !!(handle->flags & (UV__HANDLE_CLOSING | UV_HANDLE_CLOSED));
}
关闭handle,导出函数,在uv.h中声明,在handle.c中定义
void uv_close(uv_handle_t* handle,  uv_close_cb  cb)
{
    uv_loop_t* loop = handle->loop;
    //如果循环正在关闭,返回
    if (handle->flags & UV__HANDLE_CLOSING)
    {
        assert(0);
        return;
    }
    Handle->close_cb = cb;
    //根据不同的handle类型(handle->type),调用对应的关闭处理,在之后具体的类型中具体分析
    ......
}
引用handle,导出函数,在uv.h中声明,在uv-common.c中定义
void  uv_ref(uv_handle_t*  handle)
{
    //以下是uv__habdle_ref(handle)宏展开
    do 
    {
        //如果已经是引用状态,返回
        if (((handle)->flags & UV__HANDLE_REF) != 0) break;
        //设为引用状态
        (handle)->flags |= UV__HANDLE_REF;
        //正在关闭,直接返回
        if ((handle)->flags & UV__HANDLE_CLOSING) != 0) break;
        //激活状态下,将循环的active_handles加一
        if (((handle)->flags & UV__HANDLE_ACTIVE) != 0)
        //以下是uv__active_handle_add宏的展开
        do 
        {
            (handle)->loop->active_handles++;
        }
        while(0)
    }
    while(0);
}
取消handle引用,导出函数,在uv.h中声明,uv-common.c中定义
void uv_unref(uv_handle_t* handle)
{
    //以下是uv__handle_unref(handle)宏的展开
    do 
    {
        if (((handle)->flags & UV__HANDLE_REF) == 0) break;
        //去掉UV__HANDLE_REF标记
        (handle)->flags &= ~UV__HANDLE_REF;
        if (((handle)->flags & UV__HANDLE_CLOSONG) != 0) break;
        if (((handle)->flags & UV__HANDLE_ACTIVE) != 0)
        //以下是uv__active_handle_rm(h)宏的展开
        do 
        {
            (handle)->loop->active_handles--;
        }
        while(0);
    }  
    while(0)
}   
设置系统socket发送数据大小缓存,导出函数,在uv.h中声明,在uv-common.c中定义。只支持uv_tcp_t和uv_udp_t
uv_send_buffer_size(uv_handle_t* handle,  int*  value)
{
    return uv__socket_sockopt(handle, SO_SNDBUF, value);
}

内部函数

int uv__socket_sockopt(uv_handle_t* handle, int optname, int* value)
{
    int r;
    int len;
    SOCKET socket;
    if (handle == null || value == null)
        return UV_EINVAL;
    //windows平台下只支持tcp或udphandle
    if(handle->type == UV_TCP)
        socket = ((uv_tcp_t*)handle)->socket;
    else if (handle->type == UV_UDP)
        socket = ((uv_udp_t*)handle)->socket;
    else
        return UV_ENOTSUP;

    len = sizeof(*value);
    //value指向的int为0,返回目前设置
    if (*value == 0)
        r = getsocket(socket, SOL_SOCKET, optname, (char*)value, &len);
    //否则设置目前设置
    else
        r = setsocket(socket, SOL_SOCKET, optname, (const char*)value, len);
    if (r == SOCKET_ERROR)
        return uv_translate_sys_error(WSAGetLastError());
    return 0;
}

以上函数为handle的一些通用的处理函数(最后一个设置发送缓存大小的函数除外),并没有涉及到具体的handle类型(比如uv_tcp_t)以及相关类型的事件处理,这些将在之后的学习中具体分析。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
libhv和libuv都是开源的跨平台网络库,用于处理网络编程中的底层操作。它们的主要功能是封装对操作系统提供的异步IO接口,使开发者能更加方便地编写高性能的网络应用程序。 libhv是基于C语言的网络库,提供了一套简洁易用的API接口。它开发的初衷是为了满足高性能Web服务器的需求,因此在性能和效率方面有很好的表现。它支持多线程、异步IO、定时器、事件派发等功能,可以在处理大量并发连接的场景中保持低延迟和高吞吐量。libhv还能处理HTTP、WebSocket等应用层协议的解析和处理,使开发者能更加专注于业务逻辑的实现。 libuv也是跨平台的网络库,但是与libhv不同的是,libuv更加注重事件驱动的编程模型。它采用了事件循环机制,可以处理大量同时发生的事件,并将事件分发给相应的事件处理器进行处理。libuv的优点在于它的跨平台性和高性能,它的事件循环机制可以充分利用操作系统提供的异步IO接口,使得网络应用程序能在不同的操作系统上实现高度一致的性能。 在使用上,libhv和libuv都可以在不同的操作系统上运行,包括Windows、Linux、macOS等。它们都提供了丰富的API接口,使得开发者能够灵活地处理网络编程中的各种需求。同时,它们都有活跃的开发社区,可以获取到及时的技术支持和更新。 总体来说,libhv和libuv都是优秀的网络库,具有很高的性能和可靠性。它们的出现不仅使网络编程更加容易,也为开发高性能的网络应用提供了很好的选择。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值