Alby's blog

世上没有巧合,只有巧合的假象。

0%

Libuv 源码分析(4):数据结构—枚举( enum )

一、概述

Libuv 定义了若干枚举,本文集中列出方便查询( 针对 Windows 平台的枚举未完全列出)。这些枚举主要定义在如下文件:
include/uv.h
include/uv-common.h
src/unix/internal.h
src/unix/fsevents.c ( Darwin )
src/win/tty.c ( Windows )
src/win/winapi.h ( Windows )

二、用于声明枚举的映射( Map )的宏

主要目的是方便维护、减少出错几率和减少代码量。
UV_ERRNO_MAP :映射错误号和错误消息。用在 uv_strerroruv_err_name 函数。
UV_HANDLE_TYPE_MAP :映射 Handles 类型。
UV_REQ_TYPE_MAP :映射 Requests 类型。

注:映射宏一般配合命名为 “XX” 的临时宏使用。

三、include/uv.h

1、uv_errno_t :错误号

1
2
3
4
5
6
typedef enum {
#define XX(code, _) UV_ ## code = UV__ ## code,
UV_ERRNO_MAP(XX)
#undef XX
UV_ERRNO_MAX = UV__EOF - 1
} uv_errno_t;

2、uv_handle_type :Handle 类型

1
2
3
4
5
6
7
8
typedef enum {
UV_UNKNOWN_HANDLE = 0,
#define XX(uc, lc) UV_##uc,
UV_HANDLE_TYPE_MAP(XX)
#undef XX
UV_FILE,
UV_HANDLE_TYPE_MAX
} uv_handle_type;

3、uv_req_type :Request 类型

1
2
3
4
5
6
7
8
typedef enum {
UV_UNKNOWN_REQ = 0,
#define XX(uc, lc) UV_##uc,
UV_REQ_TYPE_MAP(XX)
#undef XX
UV_REQ_TYPE_PRIVATE
UV_REQ_TYPE_MAX
} uv_req_type;

4、uv_loop_option :Loop 选项

1
2
3
typedef enum {
UV_LOOP_BLOCK_SIGNAL
} uv_loop_option;

5、uv_run_mode :Loop 运行模式

1
2
3
4
5
typedef enum {
UV_RUN_DEFAULT = 0,
UV_RUN_ONCE,
UV_RUN_NOWAIT
} uv_run_mode;

6、uv_membership :UDP socket 组播选项

1
2
3
4
typedef enum {
UV_LEAVE_GROUP = 0,
UV_JOIN_GROUP
} uv_membership;

7、uv_tcp_flags :TCP socket 标记

1
2
3
4
enum uv_tcp_flags {
/* Used with uv_tcp_bind, when an IPv6 address is used. */
UV_TCP_IPV6ONLY = 1
};

8、uv_udp_flags :UDP socket 标记

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
enum uv_udp_flags {
/* Disables dual stack mode. */
UV_UDP_IPV6ONLY = 1,
/*
* Indicates message was truncated because read buffer was too small. The
* remainder was discarded by the OS. Used in uv_udp_recv_cb.
*/
UV_UDP_PARTIAL = 2,
/*
* Indicates if SO_REUSEADDR will be set when binding the handle.
* This sets the SO_REUSEPORT socket flag on the BSDs and OS X. On other
* UNIX platforms, it sets the SO_REUSEADDR flag. What that means is that
* multiple threads or processes can bind to the same address without error
* (provided they all set the flag) but only the last one to bind will receive
* any traffic, in effect "stealing" the port from the previous listener.
*/
UV_UDP_REUSEADDR = 4
};

9、uv_tty_mode_t :tty 模式

1
2
3
4
5
6
7
8
typedef enum {
/* Initial/normal terminal mode */
UV_TTY_MODE_NORMAL,
/* Raw input mode (On Windows, ENABLE_WINDOW_INPUT is also enabled) */
UV_TTY_MODE_RAW,
/* Binary-safe I/O mode for IPC (UNIX-only) */
UV_TTY_MODE_IO
} uv_tty_mode_t;

10、poll 事件

1
2
3
4
5
enum uv_poll_event {
UV_READABLE = 1,
UV_WRITABLE = 2,
UV_DISCONNECT = 4
};

11、uv_stdio_flags :标准 IO 标记

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/* uv_spawn() options. */
typedef enum {
UV_IGNORE = 0x00,
UV_CREATE_PIPE = 0x01,
UV_INHERIT_FD = 0x02,
UV_INHERIT_STREAM = 0x04,

/*
* When UV_CREATE_PIPE is specified, UV_READABLE_PIPE and UV_WRITABLE_PIPE
* determine the direction of flow, from the child process' perspective. Both
* flags may be specified to create a duplex data stream.
*/
UV_READABLE_PIPE = 0x10,
UV_WRITABLE_PIPE = 0x20
} uv_stdio_flags;

12、uv_process_flags :进程标记

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
/*
* These are the flags that can be used for the uv_process_options.flags field.
*/
enum uv_process_flags {
/*
* Set the child process' user id. The user id is supplied in the `uid` field
* of the options struct. This does not work on windows; setting this flag
* will cause uv_spawn() to fail.
*/
UV_PROCESS_SETUID = (1 << 0),
/*
* Set the child process' group id. The user id is supplied in the `gid`
* field of the options struct. This does not work on windows; setting this
* flag will cause uv_spawn() to fail.
*/
UV_PROCESS_SETGID = (1 << 1),
/*
* Do not wrap any arguments in quotes, or perform any other escaping, when
* converting the argument list into a command line string. This option is
* only meaningful on Windows systems. On UNIX it is silently ignored.
*/
UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS = (1 << 2),
/*
* Spawn the child process in a detached state - this will make it a process
* group leader, and will effectively enable the child to keep running after
* the parent exits. Note that the child process will still keep the
* parent's event loop alive unless the parent process calls uv_unref() on
* the child's process handle.
*/
UV_PROCESS_DETACHED = (1 << 3),
/*
* Hide the subprocess console window that would normally be created. This
* option is only meaningful on Windows systems. On UNIX it is silently
* ignored.
*/
UV_PROCESS_WINDOWS_HIDE = (1 << 4)
};

13、uv_dirent_type_t :dirent 结构中的文件类型字段映射

1
2
3
4
5
6
7
8
9
10
typedef enum {
UV_DIRENT_UNKNOWN,
UV_DIRENT_FILE,
UV_DIRENT_DIR,
UV_DIRENT_LINK,
UV_DIRENT_FIFO,
UV_DIRENT_SOCKET,
UV_DIRENT_CHAR,
UV_DIRENT_BLOCK
} uv_dirent_type_t;

14、uv_fs_type :文件系统操作类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
typedef enum {
UV_FS_UNKNOWN = -1,
UV_FS_CUSTOM,
UV_FS_OPEN,
UV_FS_CLOSE,
UV_FS_READ,
UV_FS_WRITE,
UV_FS_SENDFILE,
UV_FS_STAT,
UV_FS_LSTAT,
UV_FS_FSTAT,
UV_FS_FTRUNCATE,
UV_FS_UTIME,
UV_FS_FUTIME,
UV_FS_ACCESS,
UV_FS_CHMOD,
UV_FS_FCHMOD,
UV_FS_FSYNC,
UV_FS_FDATASYNC,
UV_FS_UNLINK,
UV_FS_RMDIR,
UV_FS_MKDIR,
UV_FS_MKDTEMP,
UV_FS_RENAME,
UV_FS_SCANDIR,
UV_FS_LINK,
UV_FS_SYMLINK,
UV_FS_READLINK,
UV_FS_CHOWN,
UV_FS_FCHOWN,
UV_FS_REALPATH
} uv_fs_type;

15、uv_fs_event :文件系统事件

1
2
3
4
enum uv_fs_event {
UV_RENAME = 1,
UV_CHANGE = 2
};

16、uv_fs_event_flags :文件系统事件处理标记

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/*
* Flags to be passed to uv_fs_event_start().
*/
enum uv_fs_event_flags {
/*
* By default, if the fs event watcher is given a directory name, we will
* watch for all events in that directory. This flags overrides this behavior
* and makes fs_event report only changes to the directory entry itself. This
* flag does not affect individual files watched.
* This flag is currently not implemented yet on any backend.
*/
UV_FS_EVENT_WATCH_ENTRY = 1,

/*
* By default uv_fs_event will try to use a kernel interface such as inotify
* or kqueue to detect events. This may not work on remote filesystems such
* as NFS mounts. This flag makes fs_event fall back to calling stat() on a
* regular interval.
* This flag is currently not implemented yet on any backend.
*/
UV_FS_EVENT_STAT = 2,

/*
* By default, event watcher, when watching directory, is not registering
* (is ignoring) changes in it's subdirectories.
* This flag will override this behaviour on platforms that support it.
*/
UV_FS_EVENT_RECURSIVE = 4
};

目前仅在 macOS 和 Windows 使用了 UV_FS_EVENT_RECURSIVE 标记。

四、include/uv-common.h

1、Handle 标记

1
2
3
4
5
6
7
8
9
10
11
12
13
#ifndef _WIN32
enum {
UV__HANDLE_INTERNAL = 0x8000,
UV__HANDLE_ACTIVE = 0x4000,
UV__HANDLE_REF = 0x2000,
UV__HANDLE_CLOSING = 0 /* no-op on unix */
};
#else
# define UV__HANDLE_INTERNAL 0x80
# define UV__HANDLE_ACTIVE 0x40
# define UV__HANDLE_REF 0x20
# define UV__HANDLE_CLOSING 0x01
#endif

五、src/unix/internal.h

1、Handle 标记

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/* handle flags */
enum {
UV_CLOSING = 0x01, /* uv_close() called but not finished. */
UV_CLOSED = 0x02, /* close(2) finished. */
UV_STREAM_READING = 0x04, /* uv_read_start() called. */
UV_STREAM_SHUTTING = 0x08, /* uv_shutdown() called but not complete. */
UV_STREAM_SHUT = 0x10, /* Write side closed. */
UV_STREAM_READABLE = 0x20, /* The stream is readable */
UV_STREAM_WRITABLE = 0x40, /* The stream is writable */
UV_STREAM_BLOCKING = 0x80, /* Synchronous writes. */
UV_STREAM_READ_PARTIAL = 0x100, /* read(2) read less than requested. */
UV_STREAM_READ_EOF = 0x200, /* read(2) read EOF. */
UV_TCP_NODELAY = 0x400, /* Disable Nagle. */
UV_TCP_KEEPALIVE = 0x800, /* Turn on keep-alive. */
UV_TCP_SINGLE_ACCEPT = 0x1000, /* Only accept() when idle. */
UV_HANDLE_IPV6 = 0x10000, /* Handle is bound to a IPv6 socket. */
UV_UDP_PROCESSING = 0x20000 /* Handle is running the send callback queue. */
};

2、Loop 标记

1
2
3
4
/* loop flags */
enum {
UV_LOOP_BLOCK_SIGPROF = 1
};

3、uv_clocktype_t :时钟类型

1
2
3
4
typedef enum {
UV_CLOCK_PRECISE = 0, /* Use the highest resolution clock available. */
UV_CLOCK_FAST = 1 /* Use the fastest clock with <= 1ms granularity. */
} uv_clocktype_t;

六、include/fsevents.c ( Darwin )

1、uv__cf_loop_signal_type_t :Core Foundation 事件循环信号类型

1
2
3
4
5
enum uv__cf_loop_signal_type_e {
kUVCFLoopSignalRegular,
kUVCFLoopSignalClosing
};
typedef enum uv__cf_loop_signal_type_e uv__cf_loop_signal_type_t;

七、Windows

1、_FS_INFORMATION_CLASS

1
2
3
4
5
6
7
8
9
10
11
12
13
typedef enum _FS_INFORMATION_CLASS {
FileFsVolumeInformation = 1,
FileFsLabelInformation = 2,
FileFsSizeInformation = 3,
FileFsDeviceInformation = 4,
FileFsAttributeInformation = 5,
FileFsControlInformation = 6,
FileFsFullSizeInformation = 7,
FileFsObjectIdInformation = 8,
FileFsDriverPathInformation = 9,
FileFsVolumeFlagsInformation = 10,
FileFsSectorSizeInformation = 11
} FS_INFORMATION_CLASS, *PFS_INFORMATION_CLASS;

2、uv__read_console_status_e

1
2
3
4
5
6
enum uv__read_console_status_e {
NOT_STARTED,
IN_PROGRESS,
TRAP_REQUESTED,
COMPLETED
};