Skip to content

Commit 6e9a66d

Browse files
committed
picoev: extract common code to a trace_fd/1 function, cleanup
1 parent 3939737 commit 6e9a66d

File tree

4 files changed

+22
-83
lines changed

4 files changed

+22
-83
lines changed

vlib/picoev/errors.v vlib/picoev/logging.v

+5
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,8 @@ module picoev
44
fn elog(msg string) {
55
eprintln(msg)
66
}
7+
8+
@[if trace_fd ?]
9+
fn trace_fd(msg string) {
10+
eprintln(msg)
11+
}

vlib/picoev/loop_default.c.v

+1-6
Original file line numberDiff line numberDiff line change
@@ -83,18 +83,13 @@ fn (mut pv Picoev) poll_once(max_wait_in_sec int) int {
8383
if C.FD_ISSET(target.fd, &writefds) != 0 {
8484
read_events |= picoev_write
8585
}
86-
8786
if read_events != 0 {
88-
$if trace_fd ? {
89-
eprintln('do callback ${target.fd}')
90-
}
91-
87+
trace_fd('do callback ${target.fd}')
9288
// do callback!
9389
unsafe { target.cb(target.fd, read_events, &pv) }
9490
}
9591
}
9692
}
9793
}
98-
9994
return 0
10095
}

vlib/picoev/picoev.v

+10-54
Original file line numberDiff line numberDiff line change
@@ -88,10 +88,8 @@ pub:
8888

8989
// init fills the `file_descriptors` array
9090
pub fn (mut pv Picoev) init() {
91-
assert max_fds > 0
92-
91+
// assert max_fds > 0
9392
pv.num_loops = 0
94-
9593
for i in 0 .. max_fds {
9694
pv.file_descriptors[i] = &Target{}
9795
}
@@ -103,21 +101,17 @@ pub fn (mut pv Picoev) add(fd int, events int, timeout int, callback voidptr) in
103101
if pv == unsafe { nil } || fd < 0 || fd >= max_fds {
104102
return -1 // Invalid arguments
105103
}
106-
107104
mut target := pv.file_descriptors[fd]
108105
target.fd = fd
109106
target.cb = callback
110107
target.loop_id = pv.loop.id
111108
target.events = 0
112-
113109
if pv.update_events(fd, events | picoev_add) != 0 {
114110
if pv.delete(fd) != 0 {
115111
elog('Error during del')
116112
}
117-
118113
return -1
119114
}
120-
121115
pv.set_timeout(fd, timeout)
122116
return 0
123117
}
@@ -135,18 +129,12 @@ pub fn (mut pv Picoev) delete(fd int) int {
135129
if fd < 0 || fd >= max_fds {
136130
return -1 // Invalid fd
137131
}
138-
139132
mut target := pv.file_descriptors[fd]
140-
141-
$if trace_fd ? {
142-
eprintln('remove ${fd}')
143-
}
144-
133+
trace_fd('remove ${fd}')
145134
if pv.update_events(fd, picoev_del) != 0 {
146135
elog('Error during update_events. event: `picoev.picoev_del`')
147136
return -1
148137
}
149-
150138
pv.set_timeout(fd, 0)
151139
target.loop_id = -1
152140
target.fd = 0
@@ -156,19 +144,16 @@ pub fn (mut pv Picoev) delete(fd int) int {
156144

157145
fn (mut pv Picoev) loop_once(max_wait_in_sec int) int {
158146
pv.loop.now = get_time()
159-
160147
if pv.poll_once(max_wait_in_sec) != 0 {
161148
elog('Error during poll_once')
162149
return -1
163150
}
164-
165-
if max_wait_in_sec != 0 {
166-
pv.loop.now = get_time() // Update loop start time again if waiting occurred
167-
} else {
151+
if max_wait_in_sec == 0 {
168152
// If no waiting, skip timeout handling for potential performance optimization
169153
return 0
170154
}
171-
155+
// Update loop start time again if waiting occurred
156+
pv.loop.now = get_time()
172157
pv.handle_timeout()
173158
return 0
174159
}
@@ -178,10 +163,10 @@ fn (mut pv Picoev) loop_once(max_wait_in_sec int) int {
178163
@[direct_array_access; inline]
179164
fn (mut pv Picoev) set_timeout(fd int, secs int) {
180165
assert fd < max_fds
181-
if secs != 0 {
182-
pv.timeouts[fd] = pv.loop.now + secs
183-
} else {
166+
if secs == 0 {
184167
pv.timeouts.delete(fd)
168+
} else {
169+
pv.timeouts[fd] = pv.loop.now + secs
185170
}
186171
}
187172

@@ -191,13 +176,11 @@ fn (mut pv Picoev) set_timeout(fd int, secs int) {
191176
@[direct_array_access; inline]
192177
fn (mut pv Picoev) handle_timeout() {
193178
mut to_remove := []int{}
194-
195179
for fd, timeout in pv.timeouts {
196180
if timeout <= pv.loop.now {
197181
to_remove << fd
198182
}
199183
}
200-
201184
for fd in to_remove {
202185
target := pv.file_descriptors[fd]
203186
assert target.loop_id == pv.loop.id
@@ -210,26 +193,19 @@ fn (mut pv Picoev) handle_timeout() {
210193
fn accept_callback(listen_fd int, events int, cb_arg voidptr) {
211194
mut pv := unsafe { &Picoev(cb_arg) }
212195
accepted_fd := accept(listen_fd)
213-
214196
if accepted_fd == -1 {
215197
if fatal_socket_error(accepted_fd) == false {
216198
return
217199
}
218-
219200
elog('Error during accept')
220201
return
221202
}
222-
223203
if accepted_fd >= max_fds {
224204
// should never happen
225205
close_socket(accepted_fd)
226206
return
227207
}
228-
229-
$if trace_fd ? {
230-
eprintln('accept ${accepted_fd}')
231-
}
232-
208+
trace_fd('accept ${accepted_fd}')
233209
setup_sock(accepted_fd) or {
234210
elog('setup_sock failed, fd: ${accepted_fd}, listen_fd: ${listen_fd}, err: ${err.code()}')
235211
pv.error_callback(pv.user_data, picohttpparser.Request{}, mut &picohttpparser.Response{},
@@ -256,17 +232,12 @@ fn raw_callback(fd int, events int, context voidptr) {
256232
defer {
257233
pv.idx[fd] = 0
258234
}
259-
260235
if events & picoev_timeout != 0 {
261-
$if trace_fd ? {
262-
eprintln('timeout ${fd}')
263-
}
264-
236+
trace_fd('timeout ${fd}')
265237
if !isnil(pv.raw_callback) {
266238
pv.raw_callback(mut pv, fd, events)
267239
return
268240
}
269-
270241
pv.close_conn(fd)
271242
return
272243
} else if events & picoev_read != 0 {
@@ -275,13 +246,11 @@ fn raw_callback(fd int, events int, context voidptr) {
275246
pv.raw_callback(mut pv, fd, events)
276247
return
277248
}
278-
279249
mut request_buffer := pv.buf
280250
unsafe {
281251
request_buffer += fd * pv.max_read // pointer magic
282252
}
283253
mut req := picohttpparser.Request{}
284-
285254
// Response init
286255
mut response_buffer := pv.out
287256
unsafe {
@@ -293,7 +262,6 @@ fn raw_callback(fd int, events int, context voidptr) {
293262
buf: response_buffer
294263
date: pv.date.str
295264
}
296-
297265
for {
298266
// Request parsing loop
299267
r := req_read(fd, request_buffer, pv.max_read, pv.idx[fd]) // Get data from socket
@@ -305,15 +273,12 @@ fn raw_callback(fd int, events int, context voidptr) {
305273
if fatal_socket_error(fd) == false {
306274
return
307275
}
308-
309276
elog('Error during req_read')
310-
311277
// fatal error
312278
pv.close_conn(fd)
313279
return
314280
}
315281
pv.idx[fd] += r
316-
317282
mut s := unsafe { tos(request_buffer, pv.idx[fd]) }
318283
pret := req.parse_request(s) or {
319284
// Parse error
@@ -323,15 +288,13 @@ fn raw_callback(fd int, events int, context voidptr) {
323288
if pret > 0 { // Success
324289
break
325290
}
326-
327291
assert pret == -2
328292
// request is incomplete, continue the loop
329293
if pv.idx[fd] == sizeof(request_buffer) {
330294
pv.error_callback(pv.user_data, req, mut &res, error('RequestIsTooLongError'))
331295
return
332296
}
333297
}
334-
335298
// Callback (should call .end() itself)
336299
pv.cb(pv.user_data, req, mut &res)
337300
} else if events & picoev_write != 0 {
@@ -354,7 +317,6 @@ pub fn new(config Config) !&Picoev {
354317
elog('Error during listen: ${err}')
355318
return err
356319
}
357-
358320
mut pv := &Picoev{
359321
num_loops: 1
360322
cb: config.cb
@@ -366,12 +328,10 @@ pub fn new(config Config) !&Picoev {
366328
max_read: config.max_read
367329
max_write: config.max_write
368330
}
369-
370331
if isnil(pv.raw_callback) {
371332
pv.buf = unsafe { malloc_noscan(max_fds * config.max_read + 1) }
372333
pv.out = unsafe { malloc_noscan(max_fds * config.max_write + 1) }
373334
}
374-
375335
// epoll on linux
376336
// kqueue on macos and bsd
377337
// select on windows and others
@@ -382,15 +342,12 @@ pub fn new(config Config) !&Picoev {
382342
} $else {
383343
pv.loop = create_select_loop(0) or { panic(err) }
384344
}
385-
386345
if pv.loop == unsafe { nil } {
387346
elog('Failed to create loop')
388347
close_socket(listening_socket_fd)
389348
return unsafe { nil }
390349
}
391-
392350
pv.init()
393-
394351
pv.add(listening_socket_fd, picoev_read, 0, accept_callback)
395352
return pv
396353
}
@@ -399,7 +356,6 @@ pub fn new(config Config) !&Picoev {
399356
// See also picoev.new().
400357
pub fn (mut pv Picoev) serve() {
401358
spawn update_date_string(mut pv)
402-
403359
for {
404360
pv.loop_once(1)
405361
}

vlib/picoev/socket_util.c.v

+6-23
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,7 @@ fn accept(fd int) int {
3030

3131
@[inline]
3232
fn close_socket(fd int) {
33-
$if trace_fd ? {
34-
eprintln('close ${fd}')
35-
}
36-
33+
trace_fd('close ${fd}')
3734
$if windows {
3835
C.closesocket(fd)
3936
} $else {
@@ -44,11 +41,9 @@ fn close_socket(fd int) {
4441
@[inline]
4542
fn setup_sock(fd int) ! {
4643
flag := 1
47-
4844
if C.setsockopt(fd, C.IPPROTO_TCP, C.TCP_NODELAY, &flag, sizeof(int)) < 0 {
4945
return error('setup_sock.setup_sock failed')
5046
}
51-
5247
$if freebsd {
5348
if C.fcntl(fd, C.F_SETFL, C.SOCK_NONBLOCK) != 0 {
5449
return error('fcntl failed')
@@ -88,11 +83,7 @@ fn fatal_socket_error(fd int) bool {
8883
return false
8984
}
9085
}
91-
92-
$if trace_fd ? {
93-
eprintln('fatal error ${fd}: ${C.errno}')
94-
}
95-
86+
trace_fd('fatal error ${fd}: ${C.errno}')
9687
return true
9788
}
9889

@@ -103,22 +94,16 @@ fn listen(config Config) !int {
10394
if fd == -1 {
10495
return error('Failed to create socket')
10596
}
106-
107-
$if trace_fd ? {
108-
eprintln('listen: ${fd}')
109-
}
110-
97+
trace_fd('listen: ${fd}')
11198
// Setting flags for socket
11299
flag := 1
113100
flag_zero := 0
114101
net.socket_error(C.setsockopt(fd, C.SOL_SOCKET, C.SO_REUSEADDR, &flag, sizeof(int)))!
115-
116102
if config.family == .ip6 {
117103
// set socket to dualstack so connections to both ipv4 and ipv6 addresses
118104
// can be accepted
119105
net.socket_error(C.setsockopt(fd, C.IPPROTO_IPV6, C.IPV6_V6ONLY, &flag_zero, sizeof(int)))!
120106
}
121-
122107
$if linux {
123108
// epoll socket options
124109
net.socket_error(C.setsockopt(fd, C.SOL_SOCKET, C.SO_REUSEPORT, &flag, sizeof(int)))!
@@ -131,20 +116,18 @@ fn listen(config Config) !int {
131116
sizeof(int)))!
132117
}
133118
}
134-
135119
// addr settings
136120
saddr := '${config.host}:${config.port}'
137-
addrs := net.resolve_addrs(saddr, config.family, .tcp) or { panic(err) }
121+
addrs := net.resolve_addrs(saddr, config.family, .tcp) or {
122+
panic('Error while resolving `${saddr}`, err: ${err}')
123+
}
138124
addr := addrs[0]
139125
alen := addr.len()
140-
141126
net.socket_error_message(C.bind(fd, voidptr(&addr), alen), 'binding to ${saddr} failed')!
142127
net.socket_error_message(C.listen(fd, C.SOMAXCONN), 'listening on ${saddr} with maximum backlog pending queue of ${C.SOMAXCONN}, failed')!
143-
144128
setup_sock(fd) or {
145129
config.err_cb(config.user_data, picohttpparser.Request{}, mut &picohttpparser.Response{},
146130
err)
147131
}
148-
149132
return fd
150133
}

0 commit comments

Comments
 (0)