mirror of
https://github.com/vlang/v.git
synced 2025-08-03 17:57:59 -04:00
picoev: add more logging of errors (#20558)
This commit is contained in:
parent
0367f343b0
commit
9703029dbe
@ -100,7 +100,9 @@ pub fn (mut pv Picoev) init() {
|
|||||||
// add a file descriptor to the event loop
|
// add a file descriptor to the event loop
|
||||||
@[direct_array_access]
|
@[direct_array_access]
|
||||||
pub fn (mut pv Picoev) add(fd int, events int, timeout int, callback voidptr) int {
|
pub fn (mut pv Picoev) add(fd int, events int, timeout int, callback voidptr) int {
|
||||||
assert fd < picoev.max_fds
|
if pv == unsafe { nil } || fd < 0 || fd >= picoev.max_fds {
|
||||||
|
return -1 // Invalid arguments
|
||||||
|
}
|
||||||
|
|
||||||
mut target := pv.file_descriptors[fd]
|
mut target := pv.file_descriptors[fd]
|
||||||
target.fd = fd
|
target.fd = fd
|
||||||
@ -109,11 +111,13 @@ pub fn (mut pv Picoev) add(fd int, events int, timeout int, callback voidptr) in
|
|||||||
target.events = 0
|
target.events = 0
|
||||||
|
|
||||||
if pv.update_events(fd, events | picoev.picoev_add) != 0 {
|
if pv.update_events(fd, events | picoev.picoev_add) != 0 {
|
||||||
pv.delete(fd)
|
if pv.delete(fd) != 0 {
|
||||||
|
eprintln('Error during del')
|
||||||
|
}
|
||||||
|
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
|
|
||||||
// update timeout
|
|
||||||
pv.set_timeout(fd, timeout)
|
pv.set_timeout(fd, timeout)
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
@ -128,7 +132,10 @@ pub fn (mut pv Picoev) del(fd int) int {
|
|||||||
// remove a file descriptor from the event loop
|
// remove a file descriptor from the event loop
|
||||||
@[direct_array_access]
|
@[direct_array_access]
|
||||||
pub fn (mut pv Picoev) delete(fd int) int {
|
pub fn (mut pv Picoev) delete(fd int) int {
|
||||||
assert fd < picoev.max_fds
|
if fd < 0 || fd >= picoev.max_fds {
|
||||||
|
return -1 // Invalid fd
|
||||||
|
}
|
||||||
|
|
||||||
mut target := pv.file_descriptors[fd]
|
mut target := pv.file_descriptors[fd]
|
||||||
|
|
||||||
$if trace_fd ? {
|
$if trace_fd ? {
|
||||||
@ -136,12 +143,14 @@ pub fn (mut pv Picoev) delete(fd int) int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if pv.update_events(fd, picoev.picoev_del) != 0 {
|
if pv.update_events(fd, picoev.picoev_del) != 0 {
|
||||||
|
eprintln('Error during update_events. event: `picoev.picoev_del`')
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
|
|
||||||
pv.set_timeout(fd, 0)
|
pv.set_timeout(fd, 0)
|
||||||
target.loop_id = -1
|
target.loop_id = -1
|
||||||
target.fd = 0
|
target.fd = 0
|
||||||
|
target.cb = unsafe { nil } // Clear callback to prevent accidental invocations
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -149,11 +158,15 @@ fn (mut pv Picoev) loop_once(max_wait_in_sec int) int {
|
|||||||
pv.loop.now = get_time()
|
pv.loop.now = get_time()
|
||||||
|
|
||||||
if pv.poll_once(max_wait_in_sec) != 0 {
|
if pv.poll_once(max_wait_in_sec) != 0 {
|
||||||
|
eprintln('Error during poll_once')
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
|
|
||||||
if max_wait_in_sec != 0 {
|
if max_wait_in_sec != 0 {
|
||||||
pv.loop.now = get_time()
|
pv.loop.now = get_time() // Update loop start time again if waiting occurred
|
||||||
|
} else {
|
||||||
|
// If no waiting, skip timeout handling for potential performance optimization
|
||||||
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
pv.handle_timeout()
|
pv.handle_timeout()
|
||||||
@ -197,6 +210,12 @@ fn (mut pv Picoev) handle_timeout() {
|
|||||||
fn accept_callback(listen_fd int, events int, cb_arg voidptr) {
|
fn accept_callback(listen_fd int, events int, cb_arg voidptr) {
|
||||||
mut pv := unsafe { &Picoev(cb_arg) }
|
mut pv := unsafe { &Picoev(cb_arg) }
|
||||||
accepted_fd := accept(listen_fd)
|
accepted_fd := accept(listen_fd)
|
||||||
|
|
||||||
|
if accepted_fd == -1 {
|
||||||
|
eprintln('Error during accept')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
if accepted_fd >= picoev.max_fds {
|
if accepted_fd >= picoev.max_fds {
|
||||||
// should never happen
|
// should never happen
|
||||||
close_socket(accepted_fd)
|
close_socket(accepted_fd)
|
||||||
@ -207,21 +226,22 @@ fn accept_callback(listen_fd int, events int, cb_arg voidptr) {
|
|||||||
eprintln('accept ${accepted_fd}')
|
eprintln('accept ${accepted_fd}')
|
||||||
}
|
}
|
||||||
|
|
||||||
if accepted_fd != -1 {
|
|
||||||
setup_sock(accepted_fd) or {
|
setup_sock(accepted_fd) or {
|
||||||
eprintln('setup_sock failed, fd: ${accepted_fd}, listen_fd: ${listen_fd}, err: ${err.code()}')
|
eprintln('setup_sock failed, fd: ${accepted_fd}, listen_fd: ${listen_fd}, err: ${err.code()}')
|
||||||
pv.error_callback(pv.user_data, picohttpparser.Request{}, mut &picohttpparser.Response{},
|
pv.error_callback(pv.user_data, picohttpparser.Request{}, mut &picohttpparser.Response{},
|
||||||
err)
|
err)
|
||||||
|
close_socket(accepted_fd) // Close fd on failure
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
pv.add(accepted_fd, picoev.picoev_read, pv.timeout_secs, raw_callback)
|
pv.add(accepted_fd, picoev.picoev_read, pv.timeout_secs, raw_callback)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// close_conn closes the socket `fd` and removes it from the loop
|
// close_conn closes the socket `fd` and removes it from the loop
|
||||||
@[inline]
|
@[inline]
|
||||||
pub fn (mut pv Picoev) close_conn(fd int) {
|
pub fn (mut pv Picoev) close_conn(fd int) {
|
||||||
pv.delete(fd)
|
if pv.delete(fd) != 0 {
|
||||||
|
eprintln('Error during del')
|
||||||
|
}
|
||||||
close_socket(fd)
|
close_socket(fd)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -278,6 +298,8 @@ fn raw_callback(fd int, events int, context voidptr) {
|
|||||||
pv.close_conn(fd)
|
pv.close_conn(fd)
|
||||||
return
|
return
|
||||||
} else if r == -1 {
|
} else if r == -1 {
|
||||||
|
eprintln('Error during req_read')
|
||||||
|
|
||||||
if fatal_socket_error(fd) == false {
|
if fatal_socket_error(fd) == false {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -324,7 +346,10 @@ fn default_error_callback(data voidptr, req picohttpparser.Request, mut res pico
|
|||||||
|
|
||||||
// new creates a `Picoev` struct and initializes the main loop
|
// new creates a `Picoev` struct and initializes the main loop
|
||||||
pub fn new(config Config) !&Picoev {
|
pub fn new(config Config) !&Picoev {
|
||||||
listening_socket_fd := listen(config)!
|
listening_socket_fd := listen(config) or {
|
||||||
|
eprintln('Error during listen: ${err}')
|
||||||
|
return unsafe { nil }
|
||||||
|
}
|
||||||
|
|
||||||
mut pv := &Picoev{
|
mut pv := &Picoev{
|
||||||
num_loops: 1
|
num_loops: 1
|
||||||
@ -354,6 +379,12 @@ pub fn new(config Config) !&Picoev {
|
|||||||
pv.loop = create_select_loop(0) or { panic(err) }
|
pv.loop = create_select_loop(0) or { panic(err) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if pv.loop == unsafe { nil } {
|
||||||
|
eprintln('Failed to create loop')
|
||||||
|
close_socket(listening_socket_fd)
|
||||||
|
return unsafe { nil }
|
||||||
|
}
|
||||||
|
|
||||||
pv.init()
|
pv.init()
|
||||||
|
|
||||||
pv.add(listening_socket_fd, picoev.picoev_read, 0, accept_callback)
|
pv.add(listening_socket_fd, picoev.picoev_read, 0, accept_callback)
|
||||||
@ -363,7 +394,7 @@ pub fn new(config Config) !&Picoev {
|
|||||||
// serve starts the event loop for accepting new connections
|
// serve starts the event loop for accepting new connections
|
||||||
// See also picoev.new().
|
// See also picoev.new().
|
||||||
pub fn (mut pv Picoev) serve() {
|
pub fn (mut pv Picoev) serve() {
|
||||||
spawn update_date(mut pv)
|
spawn update_date_string(mut pv)
|
||||||
|
|
||||||
for {
|
for {
|
||||||
pv.loop_once(1)
|
pv.loop_once(1)
|
||||||
@ -371,14 +402,14 @@ pub fn (mut pv Picoev) serve() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// update_date updates the date field of the Picoev instance every second for HTTP headers
|
// update_date updates the date field of the Picoev instance every second for HTTP headers
|
||||||
fn update_date(mut pv Picoev) {
|
fn update_date_string(mut pv Picoev) {
|
||||||
for {
|
for {
|
||||||
// get GMT (UTC) time for the HTTP Date header
|
// get GMT (UTC) time for the HTTP Date header
|
||||||
gmt := time.utc()
|
gmt := time.utc()
|
||||||
mut date := gmt.strftime('---, %d --- %Y %H:%M:%S GMT')
|
mut date_string := gmt.strftime('---, %d --- %Y %H:%M:%S GMT')
|
||||||
date = date.replace_once('---', gmt.weekday_str())
|
date_string = date_string.replace_once('---', gmt.weekday_str())
|
||||||
date = date.replace_once('---', gmt.smonth())
|
date_string = date_string.replace_once('---', gmt.smonth())
|
||||||
pv.date = date
|
pv.date = date_string
|
||||||
time.sleep(time.second)
|
time.sleep(time.second)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
12
vlib/picoev/picoev_test.v
Normal file
12
vlib/picoev/picoev_test.v
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
module picoev
|
||||||
|
|
||||||
|
fn test_if_all_file_descriptors_are_properly_initialized() {
|
||||||
|
mut pv := &Picoev{}
|
||||||
|
pv.init()
|
||||||
|
|
||||||
|
for i in 0 .. max_fds {
|
||||||
|
assert unsafe { pv.file_descriptors[i] } != unsafe { nil }
|
||||||
|
assert unsafe { pv.file_descriptors[i].loop_id } == -1
|
||||||
|
assert unsafe { pv.file_descriptors[i].fd } == 0
|
||||||
|
}
|
||||||
|
}
|
@ -67,11 +67,9 @@ fn setup_sock(fd int) ! {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@[inline]
|
@[inline]
|
||||||
fn req_read(fd int, b &u8, max_len int, idx int) int {
|
fn req_read(fd int, buffer &u8, max_len int, offset int) int {
|
||||||
// use `recv` instead of `read` for windows compatibility
|
// use `recv` instead of `read` for windows compatibility
|
||||||
unsafe {
|
return unsafe { C.recv(fd, buffer + offset, max_len - offset, 0) }
|
||||||
return C.recv(fd, b + idx, max_len - idx, 0)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fatal_socket_error(fd int) bool {
|
fn fatal_socket_error(fd int) bool {
|
||||||
@ -102,7 +100,9 @@ fn fatal_socket_error(fd int) bool {
|
|||||||
fn listen(config Config) !int {
|
fn listen(config Config) !int {
|
||||||
// not using the `net` modules sockets, because not all socket options are defined
|
// not using the `net` modules sockets, because not all socket options are defined
|
||||||
fd := C.socket(config.family, net.SocketType.tcp, 0)
|
fd := C.socket(config.family, net.SocketType.tcp, 0)
|
||||||
assert fd != -1
|
if fd == -1 {
|
||||||
|
return error('Failed to create socket')
|
||||||
|
}
|
||||||
|
|
||||||
$if trace_fd ? {
|
$if trace_fd ? {
|
||||||
eprintln('listen: ${fd}')
|
eprintln('listen: ${fd}')
|
||||||
|
Loading…
x
Reference in New Issue
Block a user