libuv学习笔记(3)

来源:互联网 发布:美国广播公司知乎 编辑:程序博客网 时间:2024/04/28 13:28

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 0
原创粉丝点击