Skip to content

picoev #

Description

picoev is a V implementation of picoev, which in turn is "A tiny, lightning fast event loop for network applications".

Constants #

Available on Unix only.

const max_fds = 1024

max_fds is the maximum number of file descriptors that can be managed. Many sizes depend on it, and some internal arrays are also iterated based on it, so increasing it a lot can slow down looping :-| .

Available on Windows only.

const max_fds = 4096

max_fds is the maximum number of file descriptors that can be managed. Many sizes depend on it, and some internal arrays are also iterated based on it, so increasing it a lot can slow down looping :-| . It is higher on windows, because if you start a veb/picoev webservice in a thread, the returned file descriptors can be higher than 1024 in value, especially if you also have a webview running in another thread, that also opens its own file descriptors.

Note: this works, because on windows we use select, and select on win32, is not limited to polling on only 1024 fds.

const max_queue = 4096

maximum size of the event queue.

const picoev_read = 1

event for incoming data ready to be read on a socket.

const picoev_write = 2

event for socket ready for writing.

const picoev_timeout = 4

event indicating a timeout has occurred.

const picoev_add = 0x40000000

flag for adding a file descriptor to the event loop.

const picoev_del = 0x20000000

flag for removing a file descriptor from the event loop.

const picoev_readwrite = 3

event read/write.

fn create_epoll_loop #

Available on Linux and Termux only.

fn create_epoll_loop(id int) !&EpollLoop

create_epoll_loop creates a new epoll instance and returns an EpollLoop struct with id.

fn create_kqueue_loop #

Available on macOS, FreeBSD and OpenBSD only.

fn create_kqueue_loop(id int) !&KqueueLoop

create_kqueue_loop creates a new kernel event queue with loop_id=id.

fn create_select_loop #

Available on all platforms except Linux, macOS, FreeBSD, OpenBSD and Termux.

fn create_select_loop(id int) !&SelectLoop

create_select_loop creates a new SelectLoop struct with the given id.

fn new #

fn new(config Config) !&Picoev

new creates a Picoev struct and initializes the main loop.

struct C.epoll_event #

@[packed]

Available on Linux and Termux only.

struct C.epoll_event {
	events u32
	data   C.epoll_data
}

struct C.kevent #

Available on FreeBSD and OpenBSD only.

struct C.kevent {
pub mut:
	ident int
	// uintptr_t
	filter i16
	flags  u16
	fflags u32
	data   voidptr
	// intptr_t
	udata voidptr
}

Available on macOS only.

struct C.kevent {
pub mut:
	ident  uint
	filter i16
	flags  u16
	fflags u32
	data   int
	udata  voidptr
}

struct Config #

struct Config {
pub:
	port         int = 8080
	cb           fn (voidptr, pico_http_parser.Request, mut pico_http_parser.Response)         = unsafe { nil }
	err_cb       fn (voidptr, pico_http_parser.Request, mut pico_http_parser.Response, IError) = default_error_callback
	raw_cb       fn (mut Picoev, int, int) = unsafe { nil }
	user_data    voidptr                   = unsafe { nil }
	timeout_secs int                       = 8
	max_headers  int                       = 100
	max_read     int                       = 4096
	max_write    int                       = 8192
	family       net.AddrFamily            = .ip6
	host         string
}

Config configures the Picoev instance with server settings and callbacks.

struct EpollLoop #

@[heap]

Available on Linux and Termux only.

struct EpollLoop {
mut:
	id       int
	epoll_fd int
	events   [1024]C.epoll_event
	now      i64
}

struct KqueueLoop #

@[heap]

Available on macOS, FreeBSD and OpenBSD only.

struct KqueueLoop {
mut:
	id    int
	now   i64
	kq_id int
	// -1 if not changed
	changed_fds int
	events      [1024]C.kevent
	changelist  [256]C.kevent
}

struct Picoev #

@[heap]
struct Picoev {
	cb             fn (voidptr, pico_http_parser.Request, mut pico_http_parser.Response)         = unsafe { nil }
	error_callback fn (voidptr, pico_http_parser.Request, mut pico_http_parser.Response, IError) = default_error_callback
	raw_callback   fn (mut Picoev, int, int) = unsafe { nil }

	timeout_secs int
	max_headers  int = 100
	max_read     int = 4096
	max_write    int = 8192
mut:
	loop             &LoopType = unsafe { nil }
	file_descriptors [4096]&Target // TODO: use max_fds here, instead of the hardcoded size, when the compiler allows it
	timeouts         map[int]i64
	num_loops        int

	buf &u8 = unsafe { nil }
	idx [max_fds]int
	out &u8 = unsafe { nil }

	date string
pub:
	user_data voidptr = unsafe { nil }
}

Core structure for managing the event loop and connections. Contains event loop, file descriptor table, timeouts, buffers, and configuration.

fn (Picoev) ev_set #

@[inline]

Available on macOS, FreeBSD and OpenBSD only.

fn (mut pv Picoev) ev_set(index int, operation int, events int)

ev_set sets a new kevent with file descriptor index.

fn (Picoev) init #

fn (mut pv Picoev) init()

init fills the file_descriptors array.

fn (Picoev) add #

@[direct_array_access]
fn (mut pv Picoev) add(fd int, events int, timeout int, callback voidptr) int

add a file descriptor to the event loop.

fn (Picoev) delete #

@[direct_array_access]
fn (mut pv Picoev) delete(fd int) int

remove a file descriptor from the event loop.

fn (Picoev) close_conn #

@[inline]
fn (mut pv Picoev) close_conn(fd int)

close_conn closes the socket fd and removes it from the loop.

fn (Picoev) serve #

fn (mut pv Picoev) serve()

serve starts the event loop for accepting new connections. See also picoev.new().

struct SelectLoop #

Available on all platforms except Linux, macOS, FreeBSD, OpenBSD and Termux.

struct SelectLoop {
mut:
	id  int
	now i64
}

struct Target #

struct Target {
pub mut:
	fd      int // file descriptor
	loop_id int = -1
	events  u32
	cb      fn (int, int, voidptr) = unsafe { nil }
	// used internally by the kqueue implementation
	backend int
}

Target is a data representation of everything that needs to be associated with a single file descriptor (connection).