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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
|
use std::ptr::null_mut;
use libc::{c_char, c_int, c_uint, c_ulonglong, c_void, FILE};
// TODO 检查条件编译选项
// 目前暂时全部注释掉
/// V E R S I O N I N T E R F A C E S
pub const TIMEOUT_VENDOR: &[u8; 26] = b"[email protected]";
pub const TIMEOUT_V_REL: u32 = 538313254;
pub const TIMEOUT_V_ABI: u32 = 538313252;
pub const TIMEOUT_V_API: u32 = 538313254;
extern "C" {
pub fn timeout_version() -> c_int;
pub fn timeout_vendor() -> *const c_char;
pub fn timeout_v_rel() -> c_int;
pub fn timeout_v_abi() -> c_int;
pub fn timeout_v_api() -> c_int;
}
/// I N T E G E R T Y P E I N T E R F A C E S
// 原为宏定义, 使用静态变量代替 ~~需进一步检查~~
// test-timeout.c 测试通过
pub const TIMEOUT_PRIu: &[u8; 3] = b"lu\0"; // C 语言字符串结尾 `\0`, rust 没有
pub const TIMEOUT_PRIx: &[u8; 3] = b"lx\0";
pub const TIMEOUT_PRIX: &[u8; 3] = b"lX\0";
pub const TIMEOUT_mHZ: u64 = 1000;
pub const TIMEOUT_uHZ: u64 = 1000000;
pub const TIMEOUT_nHZ: u64 = 1000000000;
pub type timeout_t = u64;
pub type timeout_error_t = usize;
/// C A L L B A C K I N T E R F A C E
///
/// Callback function parameters unspecified to make embedding into existing
/// applications easier.
// #[cfg(TIMEOUT_CB_OVERRIDE)]
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct timeout_cb {
pub fn_ptr: Option<extern "C" fn(arg: *mut c_void)>,
pub arg: *mut c_void,
}
/// T I M E O U T I N T E R F A C E S
// #[cfg(TIMEOUT_DISABLE_INTERVALS)]
pub const TIMEOUT_DEFAULT: i32 = 0;
pub const TIMEOUT_INT: i32 = 1;
pub const TIMEOUT_ABS: i32 = 2;
// TODO 宏定义 TIMEOUT_INITIALIZER timeout_setcb
// 来自 TAILQ_ENTRY 宏
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct timeout_TAILQ_ENTRY {
pub tqe_next: *mut timeout,
pub tqe_prev: *mut *mut timeout,
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct timeout {
pub flags: c_int,
pub expires: timeout_t, /* absolute expiration time */
pub pending: *mut timeout_list, /* timeout list if pending on wheel or expiry queue */
pub tqe: timeout_TAILQ_ENTRY, /* entry member for struct timeout_list lists */
// #[cfg(TIMEOUT_DISABLE_CALLBACKS)]
pub callback: timeout_cb, /* optional callback information */
// #[cfg(TIMEOUT_DISABLE_INTERVALS)]
pub interval: timeout_t, /* timeout interval if periodic */
// #[cfg(TIMEOUT_DISABLE_RELATIVE_ACCESS)]
pub timeouts: *mut timeouts, /* timeouts collection if member of */
}
impl Default for timeout {
fn default() -> Self {
timeout {
flags: 0,
expires: 0,
pending: null_mut(),
tqe: timeout_TAILQ_ENTRY {
tqe_next: null_mut(),
tqe_prev: null_mut(),
},
callback: timeout_cb {
fn_ptr: None,
arg: null_mut(),
},
interval: 0,
timeouts: null_mut(),
}
}
}
extern "C" {
/* initialize timeout structure (same as TIMEOUT_INITIALIZER) */
pub fn timeout_init(arg1: *mut timeout, arg2: c_int) -> *mut timeout;
}
// #[cfg(TIMEOUT_DISABLE_RELATIVE_ACCESS)]
extern "C" {
/* true if on timing wheel, false otherwise */
pub fn timeout_pending(arg1: *mut timeout) -> bool;
/* true if on expired queue, false otherwise */
pub fn timeout_expired(arg1: *mut timeout) -> bool;
/* remove timeout from any timing wheel (okay if not member of any) */
pub fn timeout_del(arg1: *mut timeout);
}
/// T I M I N G W H E E L I N T E R F A C E S
// 原定义在 timeout.c line 206 | TAILQ_HEAD(timeout_list, timeout);
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct timeout_list {
pub tqh_first: *mut timeout,
pub tqh_last: *mut *mut timeout,
}
// for timeouts
const WHEEL_LEN: usize = 64; // timeout.c line 132 | (1U << WHEEL_BIT ) ,WHEEL_BIT = 6
const WHEEL_NUM: usize = 4;
pub type wheel_t = u64;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct timeouts {
pub wheel: [[timeout_list; WHEEL_LEN]; WHEEL_NUM],
pub expired: timeout_list,
pub pending: [wheel_t; WHEEL_NUM],
pub curtime: timeout_t,
pub hertz: timeout_t,
}
extern "C" {
/* open a new timing wheel, setting optional HZ (for float conversions) */
pub fn timeouts_open(arg1: timeout_t, arg2: *mut timeout_error_t) -> *mut timeouts;
/* destroy timing wheel */
pub fn timeouts_close(arg1: *mut timeouts);
/* return HZ setting (for float conversions) */
pub fn timeouts_hz(arg1: *mut timeouts) -> timeout_t;
/* update timing wheel with current absolute time */
pub fn timeouts_update(arg1: *mut timeouts, arg2: timeout_t);
/* step timing wheel by relative time */
pub fn timeouts_step(arg1: *mut timeouts, arg2: timeout_t);
/* return interval to next required update */
pub fn timeouts_timeout(arg1: *mut timeouts) -> timeout_t;
/* add timeout to timing wheel */
pub fn timeouts_add(arg1: *mut timeouts, arg2: *mut timeout, arg3: timeout_t);
/* remove timeout from any timing wheel or expired queue (okay if on neither) */
pub fn timeouts_del(arg1: *mut timeouts, arg2: *mut timeout);
/* return any expired timeout (caller should loop until NULL-return) */
pub fn timeouts_get(arg1: *mut timeouts) -> *mut timeout;
/* return true if any timeouts pending on timing wheel */
pub fn timeouts_pending(arg1: *mut timeouts) -> bool;
/* return true if any timeouts on expired queue */
pub fn timeouts_expired(arg1: *mut timeouts) -> bool;
/* return true if invariants hold. describes failures to optional file handle. */
// arg2 use stderr is normal
pub fn timeouts_check(arg1: *mut timeouts, arg2: *mut FILE) -> bool;
}
extern "C" {
pub static mut stderr: *mut FILE;
}
pub const TIMEOUTS_PENDING: i32 = 16;
pub const TIMEOUTS_EXPIRED: i32 = 32;
pub const TIMEOUTS_ALL: i32 = 48;
pub const TIMEOUTS_CLEAR: i32 = 64;
// 原为 C 的宏定义 能转为 C 兼容函数
#[no_mangle]
pub extern "C" fn TIMEOUTS_IT_INITIALIZER(flags: c_int) -> timeouts_it {
timeouts_it {
flags: flags,
pc: 0,
i: 0,
j: 0,
to: null_mut(),
}
}
// 原为 C 的宏定义 能转为 C 兼容函数
#[no_mangle]
pub extern "C" fn TIMEOUTS_IT_INIT(cur: *mut timeouts_it, flags: i32) {
unsafe {
(*cur).flags = flags;
(*cur).pc = 0;
}
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct timeouts_it {
pub flags: c_int,
pub pc: c_uint,
pub i: c_uint,
pub j: c_uint,
pub to: *mut timeout,
}
impl Default for timeouts_it {
fn default() -> Self {
timeouts_it {
flags: 0,
pc: 0,
i: 0,
j: 0,
to: null_mut(),
}
}
}
/* return next timeout in pending wheel or expired queue. caller can delete
* the returned timeout, but should not otherwise manipulate the timing
* wheel. in particular, caller SHOULD NOT delete any other timeout as that
* could invalidate cursor state and trigger a use-after-free.
*/
// #[link(name = "timeout")]
extern "C" {
pub fn timeouts_next(arg1: *mut timeouts, arg2: *mut timeouts_it) -> *mut timeout;
}
/*
* Calculate the interval our caller can wait before needing to process
* events.
*/
// extern "C" {
// pub fn timeouts_int(T: *mut timeouts) -> timeout_t;
// }
// pub fn timeouts_timeout(t: *mut timeouts) -> timeout_t {
// unsafe {
// if !((*t).expired.tqh_first.is_null()) {
// return 0;
// }
// timeouts_int(t)
// }
// }
// TODO: 宏定义 TIMEOUTS_FOREACH
// B O N U S W H E E L I N T E R F A C E S
// just use for lua, not use for rust.
|