Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

libuv源码粗读(2):uv_handle_t 基础句柄结构体介绍 #29

Open
xtx1130 opened this issue Aug 29, 2018 · 0 comments
Open

libuv源码粗读(2):uv_handle_t 基础句柄结构体介绍 #29

xtx1130 opened this issue Aug 29, 2018 · 0 comments

Comments

@xtx1130
Copy link
Owner

xtx1130 commented Aug 29, 2018

本篇文章主要对uv_handle_t结构体进行展开介绍

uv_handle_t声明

直接从uv.h切入,很容易便能找到uv_handle_t结构体的声明:

typedef struct uv_handle_s uv_handle_t;

uv_handle_s的定义

uv_handle_s的定义中有如下注释:

/* The abstract base class of all handles. */
/* 所有句柄的抽象基类 */
struct uv_handle_s {
  UV_HANDLE_FIELDS
};

意即uv_##name##_t全部继承自uv_handle_t,让我们详细展开UV_HANDLE_FIELDS一窥究竟:

#define UV_HANDLE_FIELDS                                                      \
  /* public */                                                                \
  void* data;                                                                 \
  /* read-only */                                                             \
  uv_loop_t* loop;                                                            \
  uv_handle_type type;                                                        \
  /* private */                                                               \
  uv_close_cb close_cb;                                                       \
  void* handle_queue[2];                                                      \
  union {                                                                     \
    int fd;                                                                   \
    void* reserved[4];                                                        \
  } u;                                                                        \
  UV_HANDLE_PRIVATE_FIELDS                                                    \

简单对内部的数据结构做下介绍:

  • loop 为句柄所属的事件循环
  • type 为句柄类型,和uv_##name##_t强相关,对应的uv_##name##_t的type为UV_##NAME##。这种情况下可以通过handle->type很容易判断出来uv_handle_t子类的类型。
  • close_cb 句柄关闭时候执行的回调,入参参数为uv_handle_t的指针
  • handle_queue 句柄队列指针
  • u.fd 文件描述符

UV_HANDLE_PRIVATE_FIELDS展开代码如下(unix):

#define UV_HANDLE_PRIVATE_FIELDS                                              \
  uv_handle_t* next_closing;                                                  \
  unsigned int flags;                                                         \
  • next_closing 下一个需要关闭的句柄,可以使得loop->closing_handles形成一个链表结构,从而方便删除:
void uv__make_close_pending(uv_handle_t* handle) {
  assert(handle->flags & UV_HANDLE_CLOSING);
  assert(!(handle->flags & UV_HANDLE_CLOSED));
  handle->next_closing = handle->loop->closing_handles;
  handle->loop->closing_handles = handle;
}

在初始化时,会把handle->next_closing以及loop->closing_handles 全部置空。通过这段代码,可以清晰的看到在关闭句柄的时候,只需要判断handle->next_closing是否为null就可以得知所有句柄是否已经全部关闭。

  • flags 是对handle状态的标记。

继承的实现

在这里我们以uv_poll_s结构体为例,来解读一下libuv如何使用宏实现的类似继承的操作:

struct uv_poll_s {
  UV_HANDLE_FIELDS
  uv_poll_cb poll_cb;
  UV_POLL_PRIVATE_FIELDS
};

uv_poll_s数据结构中,第一个使用的宏便是UV_HANDLE_FIELDS宏,其次才为uv_poll_s的私有宏。所有的uv_##name##_t均包含了uv_handle_t的结构体变量,所以任何的uv_##name##_t都可以转换为uv_handle_t

至此,整个uv_handle_t就介绍完了。

by 小菜

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant