mirror of
https://github.com/vlang/v.git
synced 2025-09-13 22:42:26 +03:00
picoev: renaming, doc (#20567)
This commit is contained in:
parent
2d0ed2c1d6
commit
ee3cd36760
6 changed files with 91 additions and 65 deletions
|
@ -15,13 +15,14 @@ mut:
|
||||||
|
|
||||||
type LoopType = SelectLoop
|
type LoopType = SelectLoop
|
||||||
|
|
||||||
// create_select_loop creates a `SelectLoop` struct with `id`
|
// create_select_loop creates a new `SelectLoop` struct with the given `id`
|
||||||
pub fn create_select_loop(id int) !&SelectLoop {
|
pub fn create_select_loop(id int) !&SelectLoop {
|
||||||
return &SelectLoop{
|
return &SelectLoop{
|
||||||
id: id
|
id: id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// updates the events associated with a file descriptor in the event loop
|
||||||
@[direct_array_access]
|
@[direct_array_access]
|
||||||
fn (mut pv Picoev) update_events(fd int, events int) int {
|
fn (mut pv Picoev) update_events(fd int, events int) int {
|
||||||
// check if fd is in range
|
// check if fd is in range
|
||||||
|
@ -31,8 +32,10 @@ fn (mut pv Picoev) update_events(fd int, events int) int {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// performs a single iteration of the select-based event loop
|
||||||
@[direct_array_access]
|
@[direct_array_access]
|
||||||
fn (mut pv Picoev) poll_once(max_wait int) int {
|
fn (mut pv Picoev) poll_once(max_wait_in_sec int) int {
|
||||||
|
// Initializes sets for read, write, and error events
|
||||||
readfds, writefds, errorfds := C.fd_set{}, C.fd_set{}, C.fd_set{}
|
readfds, writefds, errorfds := C.fd_set{}, C.fd_set{}, C.fd_set{}
|
||||||
|
|
||||||
// setup
|
// setup
|
||||||
|
@ -42,7 +45,7 @@ fn (mut pv Picoev) poll_once(max_wait int) int {
|
||||||
|
|
||||||
mut maxfd := 0
|
mut maxfd := 0
|
||||||
|
|
||||||
// find the maximum socket for `select` and add sockets to the fd_sets
|
// finds the maximum file descriptor and adds sockets to the sets `fd_sets`.
|
||||||
for target in pv.file_descriptors {
|
for target in pv.file_descriptors {
|
||||||
if target.loop_id == pv.loop.id {
|
if target.loop_id == pv.loop.id {
|
||||||
if target.events & picoev_read != 0 {
|
if target.events & picoev_read != 0 {
|
||||||
|
@ -62,7 +65,7 @@ fn (mut pv Picoev) poll_once(max_wait int) int {
|
||||||
|
|
||||||
// select and handle sockets if any
|
// select and handle sockets if any
|
||||||
tv := C.timeval{
|
tv := C.timeval{
|
||||||
tv_sec: u64(max_wait)
|
tv_sec: u64(max_wait_in_sec)
|
||||||
tv_usec: 0
|
tv_usec: 0
|
||||||
}
|
}
|
||||||
r := C.@select(maxfd + 1, &readfds, &writefds, &errorfds, &tv)
|
r := C.@select(maxfd + 1, &readfds, &writefds, &errorfds, &tv)
|
||||||
|
@ -70,6 +73,7 @@ fn (mut pv Picoev) poll_once(max_wait int) int {
|
||||||
// timeout
|
// timeout
|
||||||
return -1
|
return -1
|
||||||
} else if r > 0 {
|
} else if r > 0 {
|
||||||
|
// Iterates through file descriptors and calls their callbacks for triggered events
|
||||||
for target in pv.file_descriptors {
|
for target in pv.file_descriptors {
|
||||||
if target.loop_id == pv.loop.id {
|
if target.loop_id == pv.loop.id {
|
||||||
// vfmt off
|
// vfmt off
|
||||||
|
|
|
@ -156,9 +156,9 @@ fn (mut pv Picoev) update_events(fd int, events int) int {
|
||||||
}
|
}
|
||||||
|
|
||||||
@[direct_array_access]
|
@[direct_array_access]
|
||||||
fn (mut pv Picoev) poll_once(max_wait int) int {
|
fn (mut pv Picoev) poll_once(max_wait_in_sec int) int {
|
||||||
ts := C.timespec{
|
ts := C.timespec{
|
||||||
tv_sec: max_wait
|
tv_sec: max_wait_in_sec
|
||||||
tv_nsec: 0
|
tv_nsec: 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -101,8 +101,8 @@ fn (mut pv Picoev) update_events(fd int, events int) int {
|
||||||
}
|
}
|
||||||
|
|
||||||
@[direct_array_access]
|
@[direct_array_access]
|
||||||
fn (mut pv Picoev) poll_once(max_wait int) int {
|
fn (mut pv Picoev) poll_once(max_wait_in_sec int) int {
|
||||||
nevents := C.epoll_wait(pv.loop.epoll_fd, &pv.loop.events, max_fds, max_wait * 1000)
|
nevents := C.epoll_wait(pv.loop.epoll_fd, &pv.loop.events, max_fds, max_wait_in_sec * 1000)
|
||||||
|
|
||||||
if nevents == -1 {
|
if nevents == -1 {
|
||||||
// timeout has occurred
|
// timeout has occurred
|
||||||
|
|
|
@ -156,9 +156,9 @@ fn (mut pv Picoev) update_events(fd int, events int) int {
|
||||||
}
|
}
|
||||||
|
|
||||||
@[direct_array_access]
|
@[direct_array_access]
|
||||||
fn (mut pv Picoev) poll_once(max_wait int) int {
|
fn (mut pv Picoev) poll_once(max_wait_in_sec int) int {
|
||||||
ts := C.timespec{
|
ts := C.timespec{
|
||||||
tv_sec: max_wait
|
tv_sec: max_wait_in_sec
|
||||||
tv_nsec: 0
|
tv_nsec: 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,28 +4,35 @@ import net
|
||||||
import picohttpparser
|
import picohttpparser
|
||||||
import time
|
import time
|
||||||
|
|
||||||
|
// maximum number of file descriptors that can be managed
|
||||||
pub const max_fds = 1024
|
pub const max_fds = 1024
|
||||||
|
|
||||||
|
// maximum size of the event queue
|
||||||
pub const max_queue = 4096
|
pub const max_queue = 4096
|
||||||
|
|
||||||
// events
|
// event for incoming data ready to be read on a socket
|
||||||
pub const picoev_read = 1
|
pub const picoev_read = 1
|
||||||
|
|
||||||
|
// event for socket ready for writing
|
||||||
pub const picoev_write = 2
|
pub const picoev_write = 2
|
||||||
|
|
||||||
|
// event indicating a timeout has occurred
|
||||||
pub const picoev_timeout = 4
|
pub const picoev_timeout = 4
|
||||||
|
|
||||||
|
// flag for adding a file descriptor to the event loop
|
||||||
pub const picoev_add = 0x40000000
|
pub const picoev_add = 0x40000000
|
||||||
|
|
||||||
|
// flag for removing a file descriptor from the event loop
|
||||||
pub const picoev_del = 0x20000000
|
pub const picoev_del = 0x20000000
|
||||||
|
|
||||||
|
// event read/write
|
||||||
pub const picoev_readwrite = 3
|
pub const picoev_readwrite = 3
|
||||||
|
|
||||||
// Target is a data representation of everything that needs to be associated with a single
|
// Target is a data representation of everything that needs to be associated with a single
|
||||||
// file descriptor (connection)
|
// file descriptor (connection)
|
||||||
pub struct Target {
|
pub struct Target {
|
||||||
pub mut:
|
pub mut:
|
||||||
fd int
|
fd int // file descriptor
|
||||||
loop_id int = -1
|
loop_id int = -1
|
||||||
events u32
|
events u32
|
||||||
cb fn (int, int, voidptr) = unsafe { nil }
|
cb fn (int, int, voidptr) = unsafe { nil }
|
||||||
|
@ -33,11 +40,12 @@ pub mut:
|
||||||
backend int
|
backend int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Config configures the Picoev instance with server settings and callbacks
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
pub:
|
pub:
|
||||||
port int = 8080
|
port int = 8080
|
||||||
cb fn (voidptr, picohttpparser.Request, mut picohttpparser.Response) = unsafe { nil }
|
cb fn (voidptr, picohttpparser.Request, mut picohttpparser.Response) = unsafe { nil }
|
||||||
err_cb fn (voidptr, picohttpparser.Request, mut picohttpparser.Response, IError) = default_err_cb
|
err_cb fn (voidptr, picohttpparser.Request, mut picohttpparser.Response, IError) = default_error_callback
|
||||||
raw_cb fn (mut Picoev, int, int) = unsafe { nil }
|
raw_cb fn (mut Picoev, int, int) = unsafe { nil }
|
||||||
user_data voidptr = unsafe { nil }
|
user_data voidptr = unsafe { nil }
|
||||||
timeout_secs int = 8
|
timeout_secs int = 8
|
||||||
|
@ -48,16 +56,21 @@ pub:
|
||||||
host string
|
host string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Core structure for managing the event loop and connections.
|
||||||
|
// Contains event loop, file descriptor table, timeouts, buffers, and configuration.
|
||||||
@[heap]
|
@[heap]
|
||||||
pub struct Picoev {
|
pub struct Picoev {
|
||||||
cb fn (voidptr, picohttpparser.Request, mut picohttpparser.Response) = unsafe { nil }
|
cb fn (voidptr, picohttpparser.Request, mut picohttpparser.Response) = unsafe { nil }
|
||||||
err_cb fn (voidptr, picohttpparser.Request, mut picohttpparser.Response, IError) = default_err_cb
|
error_callback fn (voidptr, picohttpparser.Request, mut picohttpparser.Response, IError) = default_error_callback
|
||||||
raw_cb fn (mut Picoev, int, int) = unsafe { nil }
|
raw_callback fn (mut Picoev, int, int) = unsafe { nil }
|
||||||
|
|
||||||
timeout_secs int
|
timeout_secs int
|
||||||
max_headers int = 100
|
max_headers int = 100
|
||||||
max_read int = 4096
|
max_read int = 4096
|
||||||
max_write int = 8192
|
max_write int = 8192
|
||||||
|
|
||||||
|
err_cb fn (voidptr, picohttpparser.Request, mut picohttpparser.Response, IError) = default_error_callback @[deprecated: 'use `error_callback` instead']
|
||||||
|
raw_cb fn (mut Picoev, int, int) = unsafe { nil } @[deprecated: 'use `raw_callback` instead']
|
||||||
mut:
|
mut:
|
||||||
loop &LoopType = unsafe { nil }
|
loop &LoopType = unsafe { nil }
|
||||||
file_descriptors [max_fds]&Target
|
file_descriptors [max_fds]&Target
|
||||||
|
@ -84,19 +97,19 @@ pub fn (mut pv Picoev) init() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// add adds a file descriptor to the 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, cb voidptr) int {
|
pub fn (mut pv Picoev) add(fd int, events int, timeout int, callback voidptr) int {
|
||||||
assert fd < picoev.max_fds
|
assert fd < picoev.max_fds
|
||||||
|
|
||||||
mut target := pv.file_descriptors[fd]
|
mut target := pv.file_descriptors[fd]
|
||||||
target.fd = fd
|
target.fd = fd
|
||||||
target.cb = cb
|
target.cb = callback
|
||||||
target.loop_id = pv.loop.id
|
target.loop_id = pv.loop.id
|
||||||
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.del(fd)
|
pv.delete(fd)
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,14 +118,21 @@ pub fn (mut pv Picoev) add(fd int, events int, timeout int, cb voidptr) int {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
// del removes a file descriptor from the loop
|
// del remove a file descriptor from the event loop
|
||||||
|
@[deprecated: 'use delete() instead']
|
||||||
@[direct_array_access]
|
@[direct_array_access]
|
||||||
pub fn (mut pv Picoev) del(fd int) int {
|
pub fn (mut pv Picoev) del(fd int) int {
|
||||||
|
return pv.delete(fd)
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove a file descriptor from the event loop
|
||||||
|
@[direct_array_access]
|
||||||
|
pub fn (mut pv Picoev) delete(fd int) int {
|
||||||
assert fd < picoev.max_fds
|
assert fd < picoev.max_fds
|
||||||
mut target := pv.file_descriptors[fd]
|
mut target := pv.file_descriptors[fd]
|
||||||
|
|
||||||
$if trace_fd ? {
|
$if trace_fd ? {
|
||||||
eprintln('delete ${fd}')
|
eprintln('remove ${fd}')
|
||||||
}
|
}
|
||||||
|
|
||||||
if pv.update_events(fd, picoev.picoev_del) != 0 {
|
if pv.update_events(fd, picoev.picoev_del) != 0 {
|
||||||
|
@ -125,14 +145,14 @@ pub fn (mut pv Picoev) del(fd int) int {
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut pv Picoev) loop_once(max_wait int) int {
|
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) != 0 {
|
if pv.poll_once(max_wait_in_sec) != 0 {
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
|
|
||||||
if max_wait != 0 {
|
if max_wait_in_sec != 0 {
|
||||||
pv.loop.now = get_time()
|
pv.loop.now = get_time()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,38 +193,39 @@ fn (mut pv Picoev) handle_timeout() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// accept_callback accepts a new connection from `listen_fd` and adds it to the loop
|
// accept_callback accepts a new connection from `listen_fd` and adds it to the event loop
|
||||||
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) }
|
||||||
newfd := accept(listen_fd)
|
accepted_fd := accept(listen_fd)
|
||||||
if newfd >= picoev.max_fds {
|
if accepted_fd >= picoev.max_fds {
|
||||||
// should never happen
|
// should never happen
|
||||||
close_socket(newfd)
|
close_socket(accepted_fd)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
$if trace_fd ? {
|
$if trace_fd ? {
|
||||||
eprintln('accept ${newfd}')
|
eprintln('accept ${accepted_fd}')
|
||||||
}
|
}
|
||||||
|
|
||||||
if newfd != -1 {
|
if accepted_fd != -1 {
|
||||||
setup_sock(newfd) or {
|
setup_sock(accepted_fd) or {
|
||||||
eprintln('setup_sock failed, fd: ${newfd}, listen_fd: ${listen_fd}, err: ${err.code()}')
|
eprintln('setup_sock failed, fd: ${accepted_fd}, listen_fd: ${listen_fd}, err: ${err.code()}')
|
||||||
pv.err_cb(pv.user_data, picohttpparser.Request{}, mut &picohttpparser.Response{},
|
pv.error_callback(pv.user_data, picohttpparser.Request{}, mut &picohttpparser.Response{},
|
||||||
err)
|
err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
pv.add(newfd, 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.del(fd)
|
pv.delete(fd)
|
||||||
close_socket(fd)
|
close_socket(fd)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// raw_callback handles raw events (read, write, timeout) for a file descriptor
|
||||||
@[direct_array_access]
|
@[direct_array_access]
|
||||||
fn raw_callback(fd int, events int, context voidptr) {
|
fn raw_callback(fd int, events int, context voidptr) {
|
||||||
mut pv := unsafe { &Picoev(context) }
|
mut pv := unsafe { &Picoev(context) }
|
||||||
|
@ -217,8 +238,8 @@ fn raw_callback(fd int, events int, context voidptr) {
|
||||||
eprintln('timeout ${fd}')
|
eprintln('timeout ${fd}')
|
||||||
}
|
}
|
||||||
|
|
||||||
if !isnil(pv.raw_cb) {
|
if !isnil(pv.raw_callback) {
|
||||||
pv.raw_cb(mut pv, fd, events)
|
pv.raw_callback(mut pv, fd, events)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -226,32 +247,32 @@ fn raw_callback(fd int, events int, context voidptr) {
|
||||||
return
|
return
|
||||||
} else if events & picoev.picoev_read != 0 {
|
} else if events & picoev.picoev_read != 0 {
|
||||||
pv.set_timeout(fd, pv.timeout_secs)
|
pv.set_timeout(fd, pv.timeout_secs)
|
||||||
if !isnil(pv.raw_cb) {
|
if !isnil(pv.raw_callback) {
|
||||||
pv.raw_cb(mut pv, fd, events)
|
pv.raw_callback(mut pv, fd, events)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
mut buf := pv.buf
|
mut request_buffer := pv.buf
|
||||||
unsafe {
|
unsafe {
|
||||||
buf += fd * pv.max_read // pointer magic
|
request_buffer += fd * pv.max_read // pointer magic
|
||||||
}
|
}
|
||||||
mut req := picohttpparser.Request{}
|
mut req := picohttpparser.Request{}
|
||||||
|
|
||||||
// Response init
|
// Response init
|
||||||
mut out := pv.out
|
mut response_buffer := pv.out
|
||||||
unsafe {
|
unsafe {
|
||||||
out += fd * pv.max_write // pointer magic
|
response_buffer += fd * pv.max_write // pointer magic
|
||||||
}
|
}
|
||||||
mut res := picohttpparser.Response{
|
mut res := picohttpparser.Response{
|
||||||
fd: fd
|
fd: fd
|
||||||
buf_start: out
|
buf_start: response_buffer
|
||||||
buf: out
|
buf: response_buffer
|
||||||
date: pv.date.str
|
date: pv.date.str
|
||||||
}
|
}
|
||||||
|
|
||||||
for {
|
for {
|
||||||
// Request parsing loop
|
// Request parsing loop
|
||||||
r := req_read(fd, buf, pv.max_read, pv.idx[fd]) // Get data from socket
|
r := req_read(fd, request_buffer, pv.max_read, pv.idx[fd]) // Get data from socket
|
||||||
if r == 0 {
|
if r == 0 {
|
||||||
// connection closed by peer
|
// connection closed by peer
|
||||||
pv.close_conn(fd)
|
pv.close_conn(fd)
|
||||||
|
@ -267,10 +288,10 @@ fn raw_callback(fd int, events int, context voidptr) {
|
||||||
}
|
}
|
||||||
pv.idx[fd] += r
|
pv.idx[fd] += r
|
||||||
|
|
||||||
mut s := unsafe { tos(buf, pv.idx[fd]) }
|
mut s := unsafe { tos(request_buffer, pv.idx[fd]) }
|
||||||
pret := req.parse_request(s) or {
|
pret := req.parse_request(s) or {
|
||||||
// Parse error
|
// Parse error
|
||||||
pv.err_cb(pv.user_data, req, mut &res, err)
|
pv.error_callback(pv.user_data, req, mut &res, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if pret > 0 { // Success
|
if pret > 0 { // Success
|
||||||
|
@ -279,8 +300,8 @@ fn raw_callback(fd int, events int, context voidptr) {
|
||||||
|
|
||||||
assert pret == -2
|
assert pret == -2
|
||||||
// request is incomplete, continue the loop
|
// request is incomplete, continue the loop
|
||||||
if pv.idx[fd] == sizeof(buf) {
|
if pv.idx[fd] == sizeof(request_buffer) {
|
||||||
pv.err_cb(pv.user_data, req, mut &res, error('RequestIsTooLongError'))
|
pv.error_callback(pv.user_data, req, mut &res, error('RequestIsTooLongError'))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -289,27 +310,27 @@ fn raw_callback(fd int, events int, context voidptr) {
|
||||||
pv.cb(pv.user_data, req, mut &res)
|
pv.cb(pv.user_data, req, mut &res)
|
||||||
} else if events & picoev.picoev_write != 0 {
|
} else if events & picoev.picoev_write != 0 {
|
||||||
pv.set_timeout(fd, pv.timeout_secs)
|
pv.set_timeout(fd, pv.timeout_secs)
|
||||||
if !isnil(pv.raw_cb) {
|
if !isnil(pv.raw_callback) {
|
||||||
pv.raw_cb(mut pv, fd, events)
|
pv.raw_callback(mut pv, fd, events)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn default_err_cb(data voidptr, req picohttpparser.Request, mut res picohttpparser.Response, error IError) {
|
fn default_error_callback(data voidptr, req picohttpparser.Request, mut res picohttpparser.Response, error IError) {
|
||||||
eprintln('picoev: ${error}')
|
eprintln('picoev: ${error}')
|
||||||
res.end()
|
res.end()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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 {
|
||||||
listen_fd := listen(config)!
|
listening_socket_fd := listen(config)!
|
||||||
|
|
||||||
mut pv := &Picoev{
|
mut pv := &Picoev{
|
||||||
num_loops: 1
|
num_loops: 1
|
||||||
cb: config.cb
|
cb: config.cb
|
||||||
err_cb: config.err_cb
|
error_callback: config.err_cb
|
||||||
raw_cb: config.raw_cb
|
raw_callback: config.raw_cb
|
||||||
user_data: config.user_data
|
user_data: config.user_data
|
||||||
timeout_secs: config.timeout_secs
|
timeout_secs: config.timeout_secs
|
||||||
max_headers: config.max_headers
|
max_headers: config.max_headers
|
||||||
|
@ -317,14 +338,14 @@ pub fn new(config Config) !&Picoev {
|
||||||
max_write: config.max_write
|
max_write: config.max_write
|
||||||
}
|
}
|
||||||
|
|
||||||
if isnil(pv.raw_cb) {
|
if isnil(pv.raw_callback) {
|
||||||
pv.buf = unsafe { malloc_noscan(picoev.max_fds * config.max_read + 1) }
|
pv.buf = unsafe { malloc_noscan(picoev.max_fds * config.max_read + 1) }
|
||||||
pv.out = unsafe { malloc_noscan(picoev.max_fds * config.max_write + 1) }
|
pv.out = unsafe { malloc_noscan(picoev.max_fds * config.max_write + 1) }
|
||||||
}
|
}
|
||||||
|
|
||||||
// epoll for linux
|
// epoll on linux
|
||||||
// kqueue for macos and bsd
|
// kqueue on macos and bsd
|
||||||
// select for windows and others
|
// select on windows and others
|
||||||
$if linux {
|
$if linux {
|
||||||
pv.loop = create_epoll_loop(0) or { panic(err) }
|
pv.loop = create_epoll_loop(0) or { panic(err) }
|
||||||
} $else $if freebsd || macos {
|
} $else $if freebsd || macos {
|
||||||
|
@ -335,11 +356,12 @@ pub fn new(config Config) !&Picoev {
|
||||||
|
|
||||||
pv.init()
|
pv.init()
|
||||||
|
|
||||||
pv.add(listen_fd, picoev.picoev_read, 0, accept_callback)
|
pv.add(listening_socket_fd, picoev.picoev_read, 0, accept_callback)
|
||||||
return pv
|
return pv
|
||||||
}
|
}
|
||||||
|
|
||||||
// serve starts the Picoev server
|
// serve starts the event loop for accepting new connections
|
||||||
|
// See also picoev.new().
|
||||||
pub fn (mut pv Picoev) serve() {
|
pub fn (mut pv Picoev) serve() {
|
||||||
spawn update_date(mut pv)
|
spawn update_date(mut pv)
|
||||||
|
|
||||||
|
@ -348,7 +370,7 @@ pub fn (mut pv Picoev) serve() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// update_date updates `date` on `pv` every second.
|
// update_date updates the date field of the Picoev instance every second for HTTP headers
|
||||||
fn update_date(mut pv Picoev) {
|
fn update_date(mut pv Picoev) {
|
||||||
for {
|
for {
|
||||||
// get GMT (UTC) time for the HTTP Date header
|
// get GMT (UTC) time for the HTTP Date header
|
||||||
|
|
|
@ -582,7 +582,7 @@ fn handle_read[A, X](mut pv picoev.Picoev, mut params RequestParams, fd int) {
|
||||||
// the connection should be kept open, but removed from the picoev loop.
|
// the connection should be kept open, but removed from the picoev loop.
|
||||||
// This way vweb can continue handling other connections and the user can
|
// This way vweb can continue handling other connections and the user can
|
||||||
// keep the connection open indefinitely
|
// keep the connection open indefinitely
|
||||||
pv.del(fd)
|
pv.delete(fd)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue