您的位置:首页 > 其它

libuv学习笔记(3)

2016-06-11 17:10 405 查看

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)以及相关类型的事件处理,这些将在之后的学习中具体分析。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  libuv uv-handle