-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathPerIoContext.hpp
More file actions
138 lines (105 loc) · 2.63 KB
/
PerIoContext.hpp
File metadata and controls
138 lines (105 loc) · 2.63 KB
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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#pragma once
#include "ws-util.h"
#include "MemoryPool.hpp"
#include <mutex>
/// 一些特殊的标记用 completion key
enum SpecialCompKeys {
SCK_EXIT = 1, ///< 退出
SCK_NAME_RESOLVE, ///< 异步 DNS 解释操作已完成
};
/// IOCP 异步操作上下文
struct PerIoContext {
/// 异步操作类型
enum Action {
NONE, ///< 无效状态
/// AcceptEx
///
/// 此时 #sd 属性是被接受的客户端连接套接字,
/// 而非监听套接字。
ACCEPT,
NAME_RESOLVE, ///< DNS 解析
CONNECT, ///< ConnectEx
RECV, ///< WSARecv
SEND, ///< WSASend
};
/// 构造函数
PerIoContext(SOCKET sd, Action action);
/// 复制构造函数
PerIoContext(const PerIoContext &other)
: PerIoContext(other.sd, other.action) {}
/// 是否有效
bool IsOk() const;
WSAOVERLAPPED ol; ///< 重叠结构
SOCKET sd; ///< 套接字
/// 操作类型
Action action;
};
/// 连接操作上下文
struct ConnectContext : public PerIoContext {
/// 构造函数
ConnectContext(SOCKET sd);
/// 重置
void Reset();
/// 已发送的初始数据长度
DWORD tx;
/// 是否已然连接成功
bool connected;
};
/// IOCP 接收缓冲区
struct RxContext : public PerIoContext {
enum {
BUFFER_SIZE = kBufferSize, ///< 缓冲区大小
ADDR_LEN = sizeof(sockaddr_in) + 16, ///< 地址长度
DATA_CAPACITY = BUFFER_SIZE - (ADDR_LEN * 2),
};
/// 构造函数
RxContext(SOCKET sd);
/// 复制构造函数
RxContext(const RxContext &other) = delete;
RxContext &operator=(const RxContext &other);
/// 为下次 RECV 操作做好准备
void PrepareForNextRecv();
/// 重置
void Reset();
WSABUF bufSpec; ///< 用于支持 WSARecv() 函数
CHAR buf[BUFFER_SIZE]; ///< 缓冲区
/// 缓冲区已接收的数据长度
DWORD rx;
};
/// IOCP 发送缓冲区
struct TxContext : public PerIoContext {
enum {
/// 对象池静态分配的数目
STATIC_POOL_SIZE = 16,
/// 对象池每次动态分配的数目
DYNAMIC_POOL_SIZE = STATIC_POOL_SIZE,
};
/// 构造函数
TxContext();
/// 禁止复制
TxContext(const TxContext &) = delete;
/// 析构函数
~TxContext();
/// 初始化
void Init(SOCKET sd, const char *buf, int len);
/// 总是可以重用
///
/// @todo constexpr
static bool IsRecyclable() {
return true;
}
/// 重置
void Reset();
WSABUF *buffers; ///< 缓冲区列表
DWORD nb; ///< 缓冲区个数
/// 缓冲区已被发送的数据长度
DWORD tx;
};
/// TxContext 对象内存池
class TxContextPool : public MemoryPool<TxContext, std::mutex> {
public:
/// 获取单体对象
static TxContextPool &GetInstance();
private:
TxContextPool();
};