一、概述
Libuv 和其他 C 项目一样,大量使用结构,本文主要关注结构的声明方式、结构的”继承”和结构的分类。
如果在分析具体的结构时遇到宏,可以先预处理展开宏,如:
1 | gcc -E src/uv-common.c -o src/uv-common.i -Iinclude -Isrc -Isrc/unix |
二、结构的分类
从功能上看,Libuv 的结构主要分为这几类:
Loop :事件循环( event loop )。本质上是个特殊的 Handle 。
Handles : 句柄。表示在其被激活时可以执行某些操作且持久存在的对象。
Requests : 请求。(通常)表示一个短暂存在的操作。
Other : 如: uv_buf_s
、 uv_stat_s
、uv_cpu_info_s
、uv_interface_address_s
、uv_dirent_s
、uv_passwd_s
等出于数据封装和跨平台的目的而定义的结构。
三、Handles 和 Requests 的结构“继承”
主要是结构字段的“继承”,父结构(“类”)定义基本字段,子结构在父结构尾部添加字段。在声明结构的过程中使用宏。以 uv_handle_s
、u_stream_s
和 uv_tcp_s
为例:
1 | /* The abstract base class of all handles. */ |
四、Handles 和 Requests 的继承关系图
五、结构及结构字段的命名方式
首先,以 struct uv__
(两个下划线)开头的,是 Libuv 内部使用的结构(当然,用户代码也可以使用暴露出来的结构。);以 struct uv_
(一个下划线)开头的,是公开的、可供外部使用的结构。
在声明结构时,用了不少的宏,以达到抹平不同操作系统之间的差异,“实现”结构的”封装”和”继承”,方便维护、减少出错几率和减少代码量的目的。大部分是以 _FIELDS
结尾的。
UV_PLATFORM_*_FILEDS
:
平台相关的结构字段。体现 UNIX 实现之间的差异。有两个:UV_PLATFORM_LOOP_FIELDS
和 UV_PLATFORM_FS_EVENT_FIELDS
。特别地,有一个接近此命名方式的 UV_PLATFORM_SEM_T
宏是为了抹平 Darwin 和其他 UNIX 实现之间, 信号量( semaphore )数据类型的差异。
注:
UV_PLATFORM_*_FIELDS
类似于面向对象语言中子类的定义的override public 字段。
UV_*_PRIVATE_PLATFORM_FIELDS
:
平台相关的、Handles和Requests的结构”私有”字段。有三个:UV_LOOP_PRIVATE_PLATFORM_FIELDS
、UV_STREAM_PRIVATE_PLATFORM_FIELDS
和 UV_IO_PRIVATE_PLATFORM_FIELDS
。UV_LOOP_PRIVATE_PLATFORM_FIELDS
目前是空实现;UV_STREAM_PRIVATE_PLATFORM_FIELDS
是为了抹平 Darwin 和其他 UNIX 实现之间的差异;UV_IO_PRIVATE_PLATFORM_FIELDS
是为了抹平 Darwin 、BSD 和 其他 UNIX 三者之间的差异。
注:
UV_PLATFORM_*_FIELDS
类似于面向对象语言中子类的 private 字段。
**UV_*_FIELDS
**:
平台无关的、Handles 和 Requests 的结构字段。是为了“实现”结构的”继承”。UV_*_PRIVATE_FIELDS
:
平台无关的、Handles 和 Requests 的结构”私有”字段。