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)以及相关类型的事件处理,这些将在之后的学习中具体分析。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值