core/nbio
nbio
Types
56Accept
Accept :: struct {
// Socket to accept an incoming connection on.
socket: TCP_Socket,
// When this operation expires and should be timed out.
expires: time.Time,
// The connection that was accepted.
client: TCP_Socket,
// The connection's remote origin.
client_endpoint: Endpoint,
// An error, if it occurred.
err: Accept_Error,
// Implementation specifics, private.
_impl: _Accept,
}SourceAccept_Error
Accept_Error :: Accept_ErrorSourceAddress
Address :: AddressSourceAddress_Family
Address_Family :: Address_FamilySourceAny_Socket
Any_Socket :: Any_SocketSourceAssociation_Error
Association_Error :: enum int {
None = 0,
// The given file/handle/socket was not opened in a mode that it can be made non-blocking afterwards.
//
// On Windows, this can happen when a file is not opened with the `FILE_FLAG_OVERLAPPED` flag.
// If using `core:os`, that is set when you specify the `O_NONBLOCK` flag.
// There is no way to add that after the fact.
Not_Possible_To_Associate = 1,
// The given handle is not a valid handle.
Invalid_Handle = 2,
// No network connection, or the network stack is not initialized.
Network_Unreachable = 3,
}SourceBufs
Bufs :: struct {
backing: [1][]u8,
working: struct #raw_union {
small: [1][]u8,
big: [][]u8,
},
}SourceIn order to: 1. Not require the caller to allocate their buffers (op.send.bufs and op.recv.bufs can be stack allocated) 2. Have op.send.bufs and op.recv.bufs be valid and the same content in the callback as when called 3. Be able to facilitate the all option, which requires mutating the slices (advancing them) 4. Constraint single send/recv syscalls to MAX_RW bytes
We need to copy the input buffers twice, once for a stable copy returned to the user, and one for the working copy that we mutate with all set.
Callback
Callback :: proc(op: ^Operation)SourceClosable
Closable :: union {
TCP_Socket,
UDP_Socket,
Handle,
}SourceA union of closable types that can be passed to close.
Close
Close :: struct {
// The subject to close.
subject: Closable,
// An error, if it occurred.
err: FS_Error,
// Implementation specifics, private.
_impl: _Close,
}SourceCreate_Socket_Error
Create_Socket_Error :: Create_Socket_ErrorSourceDebuggable
Debuggable :: union {
Operation_Type,
string,
int,
time.Time,
time.Duration,
}SourceDial
Dial :: struct {
// The endpoint to connect to.
endpoint: Endpoint,
// When this operation expires and should be timed out.
expires: time.Time,
// Errors that can be returned: `Create_Socket_Error`, or `Dial_Error`.
err: Network_Error,
// The socket to communicate with the connected server.
socket: TCP_Socket,
// Implementation specifics, private.
_impl: _Dial,
}SourceDial_Error
Dial_Error :: Dial_ErrorSourceEndpoint
Endpoint :: EndpointSourceEvent_Loop
Event_Loop :: struct {
impl: _Event_Loop,
allocator: runtime.Allocator,
err: General_Error,
refs: int,
now: time.Time,
// Queue that is used to queue operations from another thread to be executed on this thread.
queue: Multi_Producer_Single_Consumer,
operation_pool: pool.Pool(Operation),
}SourceAn event loop, one per thread, consider the fields private. Do not copy.
FS_Error
FS_Error :: enum i32 {
None = 0,
Unsupported = i32(PLATFORM_ERR_UNSUPPORTED),
Allocation_Failed = i32(PLATFORM_ERR_ALLOCATION_FAILED),
Timeout = i32(PLATFORM_ERR_TIMEOUT),
Invalid_Argument = i32(PLATFORM_ERR_INVALID_ARGUMENT),
Permission_Denied = i32(PLATFORM_ERR_PERMISSION_DENIED),
EOF = i32(PLATFORM_ERR_EOF),
Exists = i32(PLATFORM_ERR_EXISTS),
Not_Found = i32(PLATFORM_ERR_NOT_FOUND),
}SourceErrors gotten from file system operations.
File_Flag
File_Flag :: enum int {
// Open for reading.
Read = 0,
// Open for writing.
Write = 1,
// Append writes to the end of the file.
Append = 2,
// Create the file if it does not exist.
Create = 3,
// Fail if the file already exists (used with Create).
Excl = 4,
Sync = 5,
// Truncate the file on open.
Trunc = 6,
}SourceFile_Flags
File_Flags :: bit_set[File_Flag; int]SourceFile_Type
File_Type :: enum int {
// File type could not be determined.
Undetermined = 0,
// Regular file.
Regular = 1,
// Directory.
Directory = 2,
// Symbolic link.
Symlink = 3,
// Pipe or socket.
Pipe_Or_Socket = 4,
// Character or block device.
Device = 5,
}SourceGeneral_Error
General_Error :: enum i32 {
None = 0,
Allocation_Failed = i32(PLATFORM_ERR_ALLOCATION_FAILED),
Unsupported = i32(PLATFORM_ERR_UNSUPPORTED),
}SourceErrors regarding general usage of the event loop.
IP4_Address
IP4_Address :: IP4_AddressSourceIP6_Address
IP6_Address :: IP6_AddressSourceListen_Error
Listen_Error :: Listen_ErrorSourceMulti_Producer_Single_Consumer
Multi_Producer_Single_Consumer :: struct {
count: int,
head: int,
tail: int,
buffer: []rawptr,
mask: int,
}SourceNetwork_Error
Network_Error :: Network_ErrorSourceOpen
Open :: struct {
// Base directory the path is relative to.
dir: Handle,
// Path to the file.
path: string,
// File open mode flags.
mode: File_Flags,
// Permissions used if the file is created.
perm: Permissions,
// The opened file handle.
handle: Handle,
// An error, if it occurred.
err: FS_Error,
// Implementation specifics, private.
_impl: _Open,
}SourceOperation
Operation :: struct {
cb: Callback,
user_data: [MAX_USER_ARGUMENTS + 1]rawptr,
detached: bool,
type: Operation_Type,
specifics: Specifics,
_impl: _Operation,
_: struct #raw_union {
_pool_link: ^Operation,
l: ^Event_Loop,
},
}SourceOperation_Type
Operation_Type :: enum i32 {
None = 0,
Accept = 1,
Close = 2,
Dial = 3,
Read = 4,
Recv = 5,
Send = 6,
Write = 7,
Timeout = 8,
Poll = 9,
Send_File = 10,
Open = 11,
Stat = 12,
_Link_Timeout = 13,
_Remove = 14,
_Splice = 15,
}SourcePermission_Flag
Permission_Flag :: enum u32 {
Execute_Other = 0,
Write_Other = 1,
Read_Other = 2,
Execute_Group = 3,
Write_Group = 4,
Read_Group = 5,
Execute_User = 6,
Write_User = 7,
Read_User = 8,
}SourcePermissions
Permissions :: bit_set[Permission_Flag; u32]SourceFile permission bit-set.
This type represents POSIX-style file permissions, split into user, group, and other categories, each with read, write, and execute flags.
Poll
Poll :: struct {
// Socket to poll.
socket: Any_Socket,
// Event to poll for.
event: Poll_Event,
// When this operation expires and should be timed out.
expires: time.Time,
// Result of the poll.
result: Poll_Result,
// Implementation specifics, private.
_impl: _Poll,
}SourcePoll_Event
Poll_Event :: enum int {
// The subject is ready to be received from.
Receive = 0,
// The subject is ready to be sent to.
Send = 1,
}SourcePoll_Result
Poll_Result :: enum i32 {
// The requested event is ready.
Ready = 0,
// The operation timed out before the event became ready.
Timeout = 1,
// The socket was invalid.
Invalid_Argument = 2,
// An unspecified error occurred.
Error = 3,
}SourceRead
Read :: struct {
// Handle to read from.
handle: Handle,
// Buffer to read data into.
buf: []u8,
// Offset to read from.
offset: int,
// Whether to read until the buffer is full or an error occurs.
all: bool,
// When this operation expires and should be timed out.
expires: time.Time,
// Error, if it occurred.
err: FS_Error,
// Number of bytes read.
read: int,
// Implementation specifics, private.
_impl: _Read,
}SourceRead_Entire_File_Callback
Read_Entire_File_Callback :: proc(user_data: rawptr, data: []u8, err: Read_Entire_File_Error)SourceRead_Entire_File_Error
Read_Entire_File_Error :: struct {
operation: Operation_Type,
value: FS_Error,
}SourceRecv
Recv :: struct {
// The socket to receive from.
socket: Any_Socket,
// The buffers to receive data into.
// The outer slice is copied internally, but the backing data must remain alive.
// It is safe to access `bufs` during the callback.
bufs: [][]u8,
// If true, the operation waits until all buffers are filled (TCP only).
all: bool,
// When this operation expires and should be timed out.
expires: time.Time,
// The source endpoint data was received from (UDP only).
source: Endpoint,
// An error, if it occurred.
// If `received == 0` and `err == nil`, the connection was closed by the peer.
err: Recv_Error,
// The number of bytes received.
received: int,
// Implementation specifics, private.
_impl: _Recv,
}SourceRecv_Error
Recv_Error :: Recv_ErrorSourceSend
Send :: struct {
// The socket to send to.
socket: Any_Socket,
// The buffers to send.
// The outer slice is copied internally, but the backing data must remain alive.
// It is safe to access `bufs` during the callback.
bufs: [][]u8,
// The destination endpoint to send to (UDP only).
endpoint: Endpoint,
// If true, the operation ensures all data is sent before completing.
all: bool,
// When this operation expires and should be timed out.
expires: time.Time,
// An error, if it occurred.
err: Send_Error,
// The number of bytes sent.
sent: int,
// Implementation specifics, private.
_impl: _Send,
}SourceSend_Error
Send_Error :: Send_ErrorSourceSend_File
Send_File :: struct {
// The TCP socket to send the file over.
socket: TCP_Socket,
// The handle of the regular file to send.
file: Handle,
// When this operation expires and should be timed out.
expires: time.Time,
// The starting offset within the file.
offset: int,
// Number of bytes to send. If set to SEND_ENTIRE_FILE, the file size is retrieved
// automatically and this field is updated to reflect the full size.
nbytes: int,
// If true, the callback is triggered periodically as data is sent.
// The callback will continue to be called until `sent == nbytes` or an error occurs.
progress_updates: bool,
// Total number of bytes (so far if `progress_updates` is true).
sent: int,
// An error, if it occurred. Can be a filesystem or networking error.
err: Send_File_Error,
// Implementation specifics, private.
_impl: _Send_File,
}SourceSend_File_Error
Send_File_Error :: union {
FS_Error,
TCP_Send_Error,
}SourceSock_Addr_Ip
Sock_Addr_Ip :: struct #raw_union {
_: struct {
family: linux.Address_Family,
port: u16be,
},
ipv4: linux.Sock_Addr_In,
ipv6: linux.Sock_Addr_In6,
}SourceSocket_Protocol
Socket_Protocol :: Socket_ProtocolSourceSpecifics
Specifics :: struct #raw_union {
accept: Accept,
close: Close,
dial: Dial,
read: Read,
recv: Recv,
send: Send,
write: Write,
timeout: Timeout,
poll: Poll,
sendfile: Send_File,
open: Open,
stat: Stat,
_remove: _Remove,
_link_timeout: _Link_Timeout,
_splice: _Splice,
}SourceStat
Stat :: struct {
// Handle to stat.
handle: Handle,
// The type of the file.
type: File_Type,
// Size of the file in bytes.
size: i64,
// An error, if it occurred.
err: FS_Error,
// Implementation specifics, private.
_impl: _Stat,
}SourceTCP_Recv_Error
TCP_Recv_Error :: TCP_Recv_ErrorSourceTCP_Send_Error
TCP_Send_Error :: TCP_Send_ErrorSourceTCP_Socket
TCP_Socket :: TCP_SocketSourceTimeout
Timeout :: struct {
// Duration after which the timeout expires.
duration: time.Duration,
// Implementation specifics, private.
_impl: _Timeout,
}SourceUDP_Recv_Error
UDP_Recv_Error :: UDP_Recv_ErrorSourceUDP_Send_Error
UDP_Send_Error :: UDP_Send_ErrorSourceUDP_Socket
UDP_Socket :: UDP_SocketSourceWrite
Write :: struct {
// Handle to write to.
handle: Handle,
// Buffer containing data to write.
buf: []u8,
// Offset to write to.
offset: int,
// Whether to write until the buffer is fully written or an error occurs.
all: bool,
// When this operation expires and should be timed out.
expires: time.Time,
// Error, if it occurred.
err: FS_Error,
// Number of bytes written.
written: int,
// Implementation specifics, private.
_impl: _Write,
}Source_Platform_Error
_Platform_Error :: ErrnoSourceConstants
33CWD
CWD :: _CWDSourceSentinel handle representing the current/present working directory.
Error
Error :: intrinsics.type_merge = intrinsics.type_merge(
Network_Error,
union #shared_nil {
General_Error,
FS_Error,
},
)SourceFULLY_SUPPORTED
FULLY_SUPPORTED :: _FULLY_SUPPORTEDSourceIf the package is fully supported on the current target. If it is not it will compile but work in a matter where things are unimplemented.
Additionally if it is FULLY_SUPPORTED it may still return .Unsupported in acquire_thread_event_loop If the target does not support the needed syscalls for operating the package.
Handle
Handle :: _HandleSourceIP4_Any
IP4_Any :: IP4_AnySourceIP4_Loopback
IP4_Loopback :: IP4_LoopbackSourceIP6_Any
IP6_Any :: IP6_AnySourceIP6_Loopback
IP6_Loopback :: IP6_LoopbackSourceLINK_TIMEOUT_MASK
LINK_TIMEOUT_MASK :: 1SourceMAX_USER_ARGUMENTS
MAX_USER_ARGUMENTS :: #config(NBIO_MAX_USER_ARGUMENTS, 4)SourceThe maximum size of user arguments for an operation, can be increased at the cost of more RAM.
NBIO_DEBUG
NBIO_DEBUG :: _ = #config(NBIO_DEBUG, false)SourceNO_TIMEOUT
NO_TIMEOUT :: time.Duration = -1SourcePLATFORM_ERR_ALLOCATION_FAILED
PLATFORM_ERR_ALLOCATION_FAILED :: linux.Errno.ENOMEMSourcePLATFORM_ERR_EOF
PLATFORM_ERR_EOF :: -100SourceThere is no EOF errno, we use negative for our own error codes.
PLATFORM_ERR_EXISTS
PLATFORM_ERR_EXISTS :: linux.Errno.EEXISTSourcePLATFORM_ERR_INVALID_ARGUMENT
PLATFORM_ERR_INVALID_ARGUMENT :: linux.Errno.EINVALSourcePLATFORM_ERR_NOT_FOUND
PLATFORM_ERR_NOT_FOUND :: linux.Errno.ENOENTSourcePLATFORM_ERR_OVERFLOW
PLATFORM_ERR_OVERFLOW :: linux.Errno.E2BIGSourcePLATFORM_ERR_PERMISSION_DENIED
PLATFORM_ERR_PERMISSION_DENIED :: linux.Errno.EPERMSourcePLATFORM_ERR_TIMEOUT
PLATFORM_ERR_TIMEOUT :: linux.Errno.ECANCELEDSourcePLATFORM_ERR_UNSUPPORTED
PLATFORM_ERR_UNSUPPORTED :: linux.Errno.ENOSYSSourcePermissions_All
Permissions_All :: Permissions = Permissions_Read_All + Permissions_Write_All + Permissions_Execute_AllSourceRead, write, and execute permissions for user, group, and others.
Permissions_Default_Directory
Permissions_Default_Directory :: Permissions = Permissions_Read_All + Permissions_Write_All + Permissions_Execute_AllSourceDefault permissions used when creating a directory (read, write, and execute for everyone).
Permissions_Default_File
Permissions_Default_File :: Permissions = Permissions_Read_All + Permissions_Write_AllSourceDefault permissions used when creating a file (read and write for everyone).
Permissions_Execute_All
Permissions_Execute_All :: Permissions = Permissions{.Execute_User, .Execute_Group, .Execute_Other}SourceConvenience permission sets.
Permissions_Read_All
Permissions_Read_All :: Permissions = Permissions{.Read_User, .Read_Group, .Read_Other}SourcePermissions_Read_Write_All
Permissions_Read_Write_All :: Permissions = Permissions_Read_All + Permissions_Write_AllSourceRead and write permissions for user, group, and others.
Permissions_Write_All
Permissions_Write_All :: Permissions = Permissions{.Write_User, .Write_Group, .Write_Other}SourcePlatform_Error
Platform_Error :: _Platform_ErrorSourceQUEUE_SIZE
QUEUE_SIZE :: #config(ODIN_NBIO_QUEUE_SIZE, 2048)SourceStart file private. The size of the IO Uring queues.
REMOVED
REMOVED :: rawptr = rawptr(max(uintptr)-1)SourceSEND_ENTIRE_FILE
SEND_ENTIRE_FILE :: -1Sourceendpoint_to_string
endpoint_to_string :: net.endpoint_to_stringSourceVariables
1Procedures
155_acquire_thread_event_loop
_acquire_thread_event_loop :: proc() -> (General_Error)Source_current_thread_event_loop
_current_thread_event_loop :: proc(loc = #caller_location) -> (^Event_Loop)Source_listen_tcp
_listen_tcp :: proc(l: ^Event_Loop, endpoint: Endpoint, backlog: untyped integer = 1000, loc = #caller_location) -> (socket: TCP_Socket, err: Network_Error)Source_poly_cb
_poly_cb :: proc(C: typeid, T: typeid) -> (proc(^Operation))Source_poly_cb2
_poly_cb2 :: proc(C: typeid, T: typeid, T2: typeid) -> (proc(^Operation))Source_poly_cb3
_poly_cb3 :: proc(C: typeid, T: typeid, T2: typeid, T3: typeid) -> (proc(^Operation))Source_prep
_prep :: proc(l: ^Event_Loop, cb: Callback, type: Operation_Type) -> (^Operation)Source_put_user_data
_put_user_data :: proc(op: ^Operation, cb: C, p: T)Source_put_user_data2
_put_user_data2 :: proc(op: ^Operation, cb: C, p: T, p2: T2)Source_put_user_data3
_put_user_data3 :: proc(op: ^Operation, cb: C, p: T, p2: T2, p3: T3)Source_read_entire_file
_read_entire_file :: proc(
l: ^Event_Loop,
path: string,
user_data: rawptr,
cb: Read_Entire_File_Callback,
allocator: mem.Allocator = context.allocator,
dir: _ = CWD,
)Source_release_thread_event_loop
_release_thread_event_loop :: proc()Source_tick
_tick :: proc(l: ^Event_Loop, timeout: time.Duration) -> (err: General_Error)Sourceaccept
accept :: proc(socket: TCP_Socket, cb: Callback, timeout: time.Duration, l: ^Event_Loop) -> (^Operation)SourceUsing the given socket, accepts the next incoming connection, calling the callback when that happens.
Any user data can be set on the returned operation's user_data field. Polymorphic variants for type safe user data are available under accept_poly, accept_poly2, and accept_poly3.
Inputs:
- socket: A bound and listening socket associated with the event loop
- cb: The callback to be called when the operation finishes,
Operation.acceptwill contain results - timeout: Optional timeout for the operation, the callback will get a
.Timeouterror after that duration - l: Event loop to associate the operation with, defaults to the current thread's loop
Returns: A non-nil pointer to the operation, alive until the callback is called
accept_callback
accept_callback :: proc(op: ^Operation, res: i32)Sourceaccept_exec
accept_exec :: proc(op: ^Operation)Sourceaccept_poly
accept_poly :: proc(socket: TCP_Socket, p: T, cb: C, timeout: time.Duration, l: ^Event_Loop) -> (^Operation)SourceUsing the given socket, accepts the next incoming connection, calling the callback when that happens.
This procedure uses polymorphism for type safe user data up to a certain size.
Inputs:
- socket: A bound and listening socket associated with the event loop
- p: User data, the callback will receive this as it's second argument
- cb: The callback to be called when the operation finishes,
Operation.acceptwill contain results - timeout: Optional timeout for the operation, the callback will get a
.Timeouterror after that duration - l: Event loop to associate the operation with, defaults to the current thread's loop
Returns: A non-nil pointer to the operation, alive until the callback is called
accept_poly2
accept_poly2 :: proc(
socket: TCP_Socket,
p: T,
p2: T2,
cb: C,
timeout: time.Duration,
l: ^Event_Loop,
) -> (^Operation)SourceUsing the given socket, accepts the next incoming connection, calling the callback when that happens.
This procedure uses polymorphism for type safe user data up to a certain size.
Inputs:
- socket: A bound and listening socket associated with the event loop
- p: User data, the callback will receive this as it's second argument
- p2: User data, the callback will receive this as it's third argument
- cb: The callback to be called when the operation finishes,
Operation.acceptwill contain results - timeout: Optional timeout for the operation, the callback will get a
.Timeouterror after that duration - l: Event loop to associate the operation with, defaults to the current thread's loop
Returns: A non-nil pointer to the operation, alive until the callback is called
accept_poly3
accept_poly3 :: proc(
socket: TCP_Socket,
p: T,
p2: T2,
p3: T3,
cb: C,
timeout: time.Duration,
l: ^Event_Loop,
) -> (^Operation)SourceUsing the given socket, accepts the next incoming connection, calling the callback when that happens.
This procedure uses polymorphism for type safe user data up to a certain size.
Inputs:
- socket: A bound and listening socket associated with the event loop
- p: User data, the callback will receive this as it's second argument
- p2: User data, the callback will receive this as it's third argument
- p3: User data, the callback will receive this as it's fourth argument
- cb: The callback to be called when the operation finishes,
Operation.acceptwill contain results - timeout: Optional timeout for the operation, the callback will get a
.Timeouterror after that duration - l: Event loop to associate the operation with, defaults to the current thread's loop
Returns: A non-nil pointer to the operation, alive until the callback is called
acquire_thread_event_loop
acquire_thread_event_loop :: proc() -> (General_Error)SourceInitialize or increment the reference counted event loop for the current thread.
associate_handle
associate_handle :: proc(handle: uintptr, l: ^Event_Loop, loc = #caller_location) -> (Association_Error, Handle)SourceAssociate the given OS handle, not opened through this package, with the event loop.
Consider using this package's open or open_sync directly instead.
The handle returned is for convenience, it is actually still the same handle as given. Thus you should not close the given handle.
On Windows, this can error when a file is not opened with the FILE_FLAG_OVERLAPPED flag. If using core:os, that is set when you specify the O_NONBLOCK flag. There is no way to add that after the fact.
associate_socket
associate_socket :: proc(socket: Any_Socket, l: ^Event_Loop, loc = #caller_location) -> (Association_Error)SourceAssociate the given socket, not created through this package, with the event loop.
Consider using this package's create_socket directly instead.
bind
bind :: proc(socket: Any_Socket, ep: Endpoint) -> (err: Bind_Error)Sourcebound_endpoint
bound_endpoint :: proc(socket: Any_Socket) -> (endpoint: Endpoint, err: Socket_Info_Error)Sourcebufs_delete
bufs_delete :: proc(bufs: ^Bufs, orig: [][]u8, allocator: runtime.Allocator)Sourcebufs_init
bufs_init :: proc(bufs: ^Bufs, orig: ^[][]u8, allocator: runtime.Allocator) -> (runtime.Allocator_Error)Sourcebufs_to_process
bufs_to_process :: proc(bufs: ^Bufs, orig: [][]u8, processed: int) -> (working: [][]u8, total: int)Sourceclose
close :: proc(subject: Closable, cb: Callback, l: ^Event_Loop) -> (^Operation)SourceCloses the given subject (file or socket).
Closing something that has IO in progress may or may not cancel it, and may or may not call the callback. For consistent behavior first call remove on in progress IO.
Any user data can be set on the returned operation's user_data field. Polymorphic variants for type safe user data are available under close_poly, close_poly2, and close_poly3.
Inputs:
- subject: The subject (socket or file) to close
- cb: The optional callback to be called when the operation finishes,
Operation.closewill contain results - l: Event loop to associate the operation with, defaults to the current thread's loop
Returns: A non-nil pointer to the operation, alive until the callback is called
close_callback
close_callback :: proc(op: ^Operation, res: i32)Sourceclose_exec
close_exec :: proc(op: ^Operation)Sourceclose_poly
close_poly :: proc(subject: Closable, p: T, cb: C, l: ^Event_Loop) -> (^Operation)SourceCloses the given subject (file or socket).
Closing something that has IO in progress may or may not cancel it, and may or may not call the callback. For consistent behavior first call remove on in progress IO.
This procedure uses polymorphism for type safe user data up to a certain size.
Inputs:
- subject: The subject (socket or file) to close
- p: User data, the callback will receive this as it's second argument
- cb: The optional callback to be called when the operation finishes,
Operation.closewill contain results - l: Event loop to associate the operation with, defaults to the current thread's loop
Returns: A non-nil pointer to the operation, alive until the callback is called
close_poly2
close_poly2 :: proc(subject: Closable, p: T, p2: T2, cb: C, l: ^Event_Loop) -> (^Operation)SourceCloses the given subject (file or socket).
Closing something that has IO in progress may or may not cancel it, and may or may not call the callback. For consistent behavior first call remove on in progress IO.
This procedure uses polymorphism for type safe user data up to a certain size.
Inputs:
- subject: The subject (socket or file) to close
- p: User data, the callback will receive this as it's second argument
- p2: User data, the callback will receive this as it's third argument
- cb: The optional callback to be called when the operation finishes,
Operation.closewill contain results - l: Event loop to associate the operation with, defaults to the current thread's loop
Returns: A non-nil pointer to the operation, alive until the callback is called
close_poly3
close_poly3 :: proc(
subject: Closable,
p: T,
p2: T2,
p3: T3,
cb: C,
l: ^Event_Loop,
) -> (^Operation)SourceCloses the given subject (file or socket).
Closing something that has IO in progress may or may not cancel it, and may or may not call the callback. For consistent behavior first call remove on in progress IO.
This procedure uses polymorphism for type safe user data up to a certain size.
Inputs:
- subject: The subject (socket or file) to close
- p: User data, the callback will receive this as it's second argument
- p2: User data, the callback will receive this as it's third argument
- p3: User data, the callback will receive this as it's fourth argument
- cb: The optional callback to be called when the operation finishes,
Operation.closewill contain results - l: Event loop to associate the operation with, defaults to the current thread's loop
Returns: A non-nil pointer to the operation, alive until the callback is called
constraint_bufs_to_max_rw
constraint_bufs_to_max_rw :: proc(bufs: [][]u8) -> (constrained: [][]u8, total: int)Sourcecreate_socket
create_socket :: proc(family: Address_Family, protocol: Socket_Protocol, l: ^Event_Loop, loc = #caller_location) -> (socket: Any_Socket, err: Create_Socket_Error)SourceCreates a socket for use in nbio and relates it to the given event loop.
Inputs:
- family: Should this be an IP4 or IP6 socket
- protocol: The type of socket (TCP or UDP)
- l: The event loop to associate it with, defaults to the current thread's loop
Returns:
- socket: The created socket, consider
create_{udp|tcp}_socketfor a typed socket instead of the union - err: A network error (
Create_Socket_Error, orSet_Blocking_Error) which happened while opening
create_tcp_socket
create_tcp_socket :: proc(family: Address_Family, l: ^Event_Loop, loc = #caller_location) -> (net.TCP_Socket, Create_Socket_Error)SourceCreates a TCP socket for use in nbio and relates it to the given event loop.
Inputs:
- family: Should this be an IP4 or IP6 socket
- l: The event loop to associate it with, defaults to the current thread's loop
Returns:
- socket: The created TCP socket
- err: A network error (
Create_Socket_Error, orSet_Blocking_Error) which happened while opening
create_udp_socket
create_udp_socket :: proc(family: Address_Family, l: ^Event_Loop, loc = #caller_location) -> (net.UDP_Socket, Create_Socket_Error)SourceCreates a UDP socket for use in nbio and relates it to the given event loop.
Inputs:
- family: Should this be an IP4 or IP6 socket
- l: The event loop to associate it with, defaults to the current thread's loop
Returns:
- socket: The created UDP socket
- err: A network error (
Create_Socket_Error, orSet_Blocking_Error) which happened while opening
current_thread_event_loop
current_thread_event_loop :: proc(loc = #caller_location) -> (^Event_Loop)Sourcedebug
debug :: proc(contents, location = #caller_location)Sourcedetach
detach :: proc(op: ^Operation)SourceDetach an operation from the package's lifetime management.
By default the operation's lifetime is managed by the package and freed after a callback is called. Calling this function detaches the operation from this lifetime. You are expected to call reattach to give the package back this operation.
dial
dial :: proc(endpoint: Endpoint, cb: Callback, timeout: time.Duration, l: ^Event_Loop) -> (^Operation)SourceDials the given endpoint.
Any user data can be set on the returned operation's user_data field. Polymorphic variants for type safe user data are available under dial_poly, dial_poly2, and dial_poly3.
Inputs:
- endpoint: The endpoint to connect to
- cb: The callback to be called when the operation finishes,
Operation.dialwill contain results - timeout: Optional timeout for the operation, the callback will get a
.Timeouterror after that duration - l: Event loop to associate the operation with, defaults to the current thread's loop
Returns: A non-nil pointer to the operation, alive until the callback is called
dial_callback
dial_callback :: proc(op: ^Operation, res: i32)Sourcedial_exec
dial_exec :: proc(op: ^Operation)Sourcedial_poly
dial_poly :: proc(endpoint: Endpoint, p: T, cb: C, timeout: time.Duration, l: ^Event_Loop) -> (^Operation)SourceDials the given endpoint.
This procedure uses polymorphism for type safe user data up to a certain size.
Inputs:
- endpoint: The endpoint to connect to
- p: User data, the callback will receive this as it's second argument
- cb: The callback to be called when the operation finishes,
Operation.dialwill contain results - timeout: Optional timeout for the operation, the callback will get a
.Timeouterror after that duration - l: Event loop to associate the operation with, defaults to the current thread's loop
Returns: A non-nil pointer to the operation, alive until the callback is called
dial_poly2
dial_poly2 :: proc(
endpoint: Endpoint,
p: T,
p2: T2,
cb: C,
timeout: time.Duration,
l: ^Event_Loop,
) -> (^Operation)SourceDials the given endpoint.
This procedure uses polymorphism for type safe user data up to a certain size.
Inputs:
- endpoint: The endpoint to connect to
- p: User data, the callback will receive this as it's second argument
- p2: User data, the callback will receive this as it's third argument
- cb: The callback to be called when the operation finishes,
Operation.dialwill contain results - timeout: Optional timeout for the operation, the callback will get a
.Timeouterror after that duration - l: Event loop to associate the operation with, defaults to the current thread's loop
Returns: A non-nil pointer to the operation, alive until the callback is called
dial_poly3
dial_poly3 :: proc(
endpoint: Endpoint,
p: T,
p2: T2,
p3: T3,
cb: C,
timeout: time.Duration,
l: ^Event_Loop,
) -> (^Operation)SourceDials the given endpoint.
This procedure uses polymorphism for type safe user data up to a certain size.
Inputs:
- endpoint: The endpoint to connect to
- p: User data, the callback will receive this as it's second argument
- p2: User data, the callback will receive this as it's third argument
- p3: User data, the callback will receive this as it's fourth argument
- cb: The callback to be called when the operation finishes,
Operation.dialwill contain results - timeout: Optional timeout for the operation, the callback will get a
.Timeouterror after that duration - l: Event loop to associate the operation with, defaults to the current thread's loop
Returns: A non-nil pointer to the operation, alive until the callback is called
endpoint_to_sockaddr_any
endpoint_to_sockaddr_any :: proc(ep: Endpoint) -> (sockaddr: linux.Sock_Addr_Any)Sourceendpoint_to_sockaddr_ip
endpoint_to_sockaddr_ip :: proc(ep: Endpoint) -> (sockaddr: Sock_Addr_Ip)Sourceenqueue
enqueue :: proc(op: ^Operation, sqe: ^linux.IO_Uring_SQE, ok: bool)Sourceerror_string
error_string :: proc(err: Error) -> (string)Sourceerror_string_recv
error_string_recv :: proc(recv_err: Recv_Error) -> (string)Sourceerror_string_send
error_string_send :: proc(send_err: Send_Error) -> (string)Sourceerror_string_sendfile
error_string_sendfile :: proc(send_err: Send_File_Error) -> (string)Sourceexec
exec :: proc(op: ^Operation, trigger_wake_up: untyped boolean = true)SourceExecute an operation.
If the operation is attached to another thread's event loop, it is queued to be executed on that event loop, optionally waking that loop up (from a blocking tick) with trigger_wake_up.
family_from_endpoint
family_from_endpoint :: proc(ep: Endpoint) -> (Address_Family)Sourcehandle_completed
handle_completed :: proc(op: ^Operation, res: i32)Sourcelink_timeout
link_timeout :: proc(target: ^Operation, expires: time.Time)Sourcelink_timeout_callback
link_timeout_callback :: proc(op: ^Operation, res: i32)Sourcelisten_tcp
listen_tcp :: proc(endpoint: Endpoint, backlog: untyped integer = 1000, l: ^Event_Loop, loc = #caller_location) -> (socket: TCP_Socket, err: net.Network_Error)SourceCreates a socket, sets non blocking mode, relates it to the given IO, binds the socket to the given endpoint and starts listening.
Inputs:
- endpoint: Where to bind the socket to
- backlog: The maximum length to which the queue of pending connections may grow, before refusing connections
- l: The event loop to associate the socket with, defaults to the current thread's loop
Returns:
- socket: The opened, bound and listening socket
- err: A network error (
Create_Socket_Error,Bind_Error, orListen_Error) that has happened
mpsc_cap
mpsc_cap :: proc(mpscq: ^Multi_Producer_Single_Consumer) -> (int)Sourcempsc_count
mpsc_count :: proc(mpscq: ^Multi_Producer_Single_Consumer) -> (int)Sourcempsc_dequeue
mpsc_dequeue :: proc(mpscq: ^Multi_Producer_Single_Consumer) -> (rawptr)Sourcempsc_destroy
mpsc_destroy :: proc(mpscq: ^Multi_Producer_Single_Consumer, allocator: runtime.Allocator)Sourcempsc_enqueue
mpsc_enqueue :: proc(mpscq: ^Multi_Producer_Single_Consumer, obj: rawptr) -> (bool)Sourcempsc_init
mpsc_init :: proc(mpscq: ^Multi_Producer_Single_Consumer, cap: int, allocator: runtime.Allocator) -> (runtime.Allocator_Error)Sourcenext_tick
next_tick :: proc(cb: Callback, l: ^Event_Loop) -> (^Operation)SourceSchedules an operation that completes on the next event loop tick.
This is equivalent to timeout(0, ...).
next_tick_poly
next_tick_poly :: proc(p: T, cb: C, l: ^Event_Loop) -> (^Operation)SourceSchedules an operation that completes on the next event loop tick.
This is equivalent to timeout_poly(0, ...).
next_tick_poly2
next_tick_poly2 :: proc(p: T, p2: T2, cb: C, l: ^Event_Loop) -> (^Operation)SourceSchedules an operation that completes on the next event loop tick.
This is equivalent to timeout_poly2(0, ...).
next_tick_poly3
next_tick_poly3 :: proc(p: T, p2: T2, p3: T3, cb: C, l: ^Event_Loop) -> (^Operation)SourceSchedules an operation that completes on the next event loop tick.
This is equivalent to timeout_poly3(0, ...).
now
now :: proc() -> (time.Time)SourceReturns the current time (cached at most at the beginning of the current tick).
ns_to_time_spec
ns_to_time_spec :: proc(nsec: i64) -> (linux.Time_Spec)Sourcenum_waiting
num_waiting :: proc(l: Maybe(^Event_Loop)) -> (int)SourceReturns the number of in-progress operations to be completed on the event loop.
open
open :: proc(
path: string,
cb: Callback,
mode: File_Flags,
perm: Permissions,
dir: Handle,
l: ^Event_Loop,
) -> (^Operation)SourceOpens a file and associates it with the event loop.
Any user data can be set on the returned operation's user_data field. Polymorphic variants for type safe user data are available under open_poly, open_poly2, and open_poly3.
Inputs:
- path: Path to the file, if not absolute: relative from
dir - cb: The callback to be called when the operation finishes,
Operation.openwill contain results - mode: File open mode flags, defaults to read-only
- perm: Permissions to use when creating a file, defaults to read+write for everybody
- dir: Directory that
pathis relative from (if it is relative), defaults to the current working directory - l: Event loop to associate the operation with, defaults to the current thread's loop
Returns: A non-nil pointer to the operation, alive until the callback is called
open_callback
open_callback :: proc(op: ^Operation, res: i32)Sourceopen_exec
open_exec :: proc(op: ^Operation)Sourceopen_poly
open_poly :: proc(
path: string,
p: T,
cb: C,
mode: File_Flags,
perm: Permissions,
dir: Handle,
l: ^Event_Loop,
) -> (^Operation)SourceOpens a file and associates it with the event loop.
This procedure uses polymorphism for type safe user data up to a certain size.
Inputs:
- path: Path to the file, if not absolute: relative from
dir - p: User data, the callback will receive this as its second argument
- cb: The callback to be called when the operation finishes,
Operation.openwill contain results - mode: File open mode flags, defaults to read-only
- perm: Permissions to use when creating a file, defaults to read+write for everybody
- dir: Directory that
pathis relative from (if it is relative), defaults to the current working directory - l: Event loop to associate the operation with, defaults to the current thread's loop
Returns: A non-nil pointer to the operation, alive until the callback is called
open_poly2
open_poly2 :: proc(
path: string,
p: T,
p2: T2,
cb: C,
mode: File_Flags,
perm: Permissions,
dir: Handle,
l: ^Event_Loop,
) -> (^Operation)SourceOpens a file and associates it with the event loop.
This procedure uses polymorphism for type safe user data up to a certain size.
Inputs:
- path: Path to the file, if not absolute: relative from
dir - p: User data, the callback will receive this as its second argument
- p2: User data, the callback will receive this as its third argument
- cb: The callback to be called when the operation finishes,
Operation.openwill contain results - mode: File open mode flags, defaults to read-only
- perm: Permissions to use when creating a file, defaults to read+write for everybody
- dir: Directory that
pathis relative from (if it is relative), defaults to the current working directory - l: Event loop to associate the operation with, defaults to the current thread's loop
Returns: A non-nil pointer to the operation, alive until the callback is called
open_poly3
open_poly3 :: proc(
path: string,
p: T,
p2: T2,
p3: T3,
cb: C,
mode: File_Flags,
perm: Permissions,
dir: Handle,
l: ^Event_Loop,
) -> (^Operation)SourceAsynchronously opens a file and associates it with the event loop.
This procedure uses polymorphism for type safe user data up to a certain size.
Inputs:
- path: Path to the file, if not absolute: relative from
dir - p: User data, the callback will receive this as its second argument
- p2: User data, the callback will receive this as its third argument
- p3: User data, the callback will receive this as its fourth argument
- cb: The callback to be called when the operation finishes,
Operation.openwill contain results - mode: File open mode flags, defaults to read-only
- perm: Permissions to use when creating a file, defaults to read+write for everybody
- dir: Directory that
pathis relative from (if it is relative), defaults to the current working directory - l: Event loop to associate the operation with, defaults to the current thread's loop
Returns: A non-nil pointer to the operation, alive until the callback is called
open_sync
open_sync :: proc(
path: string,
dir: Handle,
mode: File_Flags,
perm: _ = Permissions_Default_File,
l: ^Event_Loop,
loc: _ = #caller_location,
) -> (handle: Handle, err: FS_Error)SourceOpens a file and associates it with the event loop.
Inputs:
- path: path to the file, if not absolute: relative from
dir - dir: directory that
pathis relative from (if it is relative), defaults to the current working directory - mode: open mode, defaults to read-only
- perm: permissions to use when creating a file, defaults to read+write for everybody
- l: event loop to associate the file with, defaults to the current thread's
Returns:
- handle: The file handle
- err: An error if it occurred
parse_endpoint
parse_endpoint :: proc(endpoint_str: string) -> (ep: Endpoint, ok: bool)Sourcepoll
poll :: proc(socket: Any_Socket, event: Poll_Event, cb: Callback, timeout: time.Duration, l: ^Event_Loop) -> (^Operation)SourcePoll a socket for readiness.
NOTE: this is provided to help with "legacy" APIs that require polling behavior. If you can avoid it and use the other procs in this package, do so.
Any user data can be set on the returned operation's user_data field. Polymorphic variants for type safe user data are available under poll_poly, poll_poly2, and poll_poly3.
Inputs:
- socket: Socket to poll that is associated with the event loop
- event: Event to poll for
- cb: The callback to be called when the operation finishes,
Operation.pollwill contain results - timeout: Optional timeout for the operation, the callback will receive a
.Timeoutresult after that duration - l: Event loop to associate the operation with, defaults to the current thread's loop
Returns: A non-nil pointer to the operation, alive until the callback is called
poll_callback
poll_callback :: proc(op: ^Operation, res: i32)Sourcepoll_exec
poll_exec :: proc(op: ^Operation)Sourcepoll_poly
poll_poly :: proc(
socket: Any_Socket,
event: Poll_Event,
p: T,
cb: C,
timeout: time.Duration,
l: ^Event_Loop,
) -> (^Operation)SourcePoll a socket for readiness.
NOTE: this is provided to help with "legacy" APIs that require polling behavior. If you can avoid it and use the other procs in this package, do so.
This procedure uses polymorphism for type safe user data up to a certain size.
Inputs:
- socket: Socket to poll that is associated with the event loop
- event: Event to poll for
- p: User data, the callback will receive this as its second argument
- cb: The callback to be called when the operation finishes,
Operation.pollwill contain results - timeout: Optional timeout for the operation, the callback will receive a
.Timeoutresult after that duration - l: Event loop to associate the operation with, defaults to the current thread's loop
Returns: A non-nil pointer to the operation, alive until the callback is called
poll_poly2
poll_poly2 :: proc(
socket: Any_Socket,
event: Poll_Event,
p: T,
p2: T2,
cb: C,
timeout: time.Duration,
l: ^Event_Loop,
) -> (^Operation)SourcePoll a socket for readiness.
NOTE: this is provided to help with "legacy" APIs that require polling behavior. If you can avoid it and use the other procs in this package, do so.
This procedure uses polymorphism for type safe user data up to a certain size.
Inputs:
- socket: Socket to poll that is associated with the event loop
- event: Event to poll for
- p: User data, the callback will receive this as its second argument
- p2: User data, the callback will receive this as its third argument
- cb: The callback to be called when the operation finishes,
Operation.pollwill contain results - timeout: Optional timeout for the operation, the callback will receive a
.Timeoutresult after that duration - l: Event loop to associate the operation with, defaults to the current thread's loop
Returns: A non-nil pointer to the operation, alive until the callback is called
poll_poly3
poll_poly3 :: proc(
socket: Any_Socket,
event: Poll_Event,
p: T,
p2: T2,
p3: T3,
cb: C,
timeout: time.Duration,
l: ^Event_Loop,
) -> (^Operation)SourcePoll a socket for readiness.
NOTE: this is provided to help with "legacy" APIs that require polling behavior. If you can avoid it and use the other procs in this package, do so.
This procedure uses polymorphism for type safe user data up to a certain size.
Inputs:
- socket: Socket to poll that is associated with the event loop
- event: Event to poll for
- p: User data, the callback will receive this as its second argument
- p2: User data, the callback will receive this as its third argument
- p3: User data, the callback will receive this as its fourth argument
- cb: The callback to be called when the operation finishes,
Operation.pollwill contain results - timeout: Optional timeout for the operation, the callback will receive a
.Timeoutresult after that duration - l: Event loop to associate the operation with, defaults to the current thread's loop
Returns: A non-nil pointer to the operation, alive until the callback is called
prep_accept
prep_accept :: proc(socket: TCP_Socket, cb: Callback, timeout: time.Duration, l: ^Event_Loop) -> (^Operation)SourceRetrieves and preps an operation to do an accept without executing it.
Executing can then be done with the exec procedure.
The timeout is calculated from the time when this procedure was called, not from when it's executed.
Any user data can be set on the returned operation's user_data field.
Inputs:
- socket: A bound and listening socket associated with the event loop
- cb: The callback to be called when the operation finishes,
Operation.acceptwill contain results - timeout: Optional timeout for the operation, the callback will get a
.Timeouterror after that duration - l: Event loop to associate the operation with, defaults to the current thread's loop
Returns: A non-nil pointer to the operation, alive until the callback is called
prep_close
prep_close :: proc(subject: Closable, cb: Callback, l: ^Event_Loop) -> (^Operation)SourceRetrieves and preps an operation to do a close without executing it.
Executing can then be done with the exec procedure.
Closing something that has IO in progress may or may not cancel it, and may or may not call the callback. For consistent behavior first call remove on in progress IO.
Any user data can be set on the returned operation's user_data field.
Inputs:
- subject: The subject (socket or file) to close
- cb: The optional callback to be called when the operation finishes,
Operation.closewill contain results - l: Event loop to associate the operation with, defaults to the current thread's loop
Returns: A non-nil pointer to the operation, alive until the callback is called
prep_dial
prep_dial :: proc(endpoint: Endpoint, cb: Callback, timeout: time.Duration, l: ^Event_Loop) -> (^Operation)SourceRetrieves and preps an operation to do a dial operation without executing it.
Executing can then be done with the exec procedure.
The timeout is calculated from the time when this procedure was called, not from when it's executed.
Any user data can be set on the returned operation's user_data field.
Inputs:
- endpoint: The endpoint to connect to
- cb: The callback to be called when the operation finishes,
Operation.dialwill contain results - timeout: Optional timeout for the operation, the callback will get a
.Timeouterror after that duration - l: Event loop to associate the operation with, defaults to the current thread's loop
Returns: A non-nil pointer to the operation, alive until the callback is called
prep_next_tick
prep_next_tick :: proc(cb: Callback, l: ^Event_Loop) -> (^Operation)SourceRetrieves and preps an operation that completes on the next event loop tick.
This is equivalent to prep_timeout(0, ...).
prep_open
prep_open :: proc(
path: string,
cb: Callback,
mode: File_Flags,
perm: Permissions,
dir: Handle,
l: ^Event_Loop,
) -> (^Operation)SourceRetrieves and preps an operation to open a file without executing it.
Executing can then be done with the exec procedure.
Any user data can be set on the returned operation's user_data field.
Inputs:
- path: Path to the file, if not absolute: relative from
dir - cb: The callback to be called when the operation finishes,
Operation.openwill contain results - mode: File open mode flags, defaults to read-only
- perm: Permissions to use when creating a file, defaults to read+write for everybody
- dir: Directory that
pathis relative from (if it is relative), defaults to the current working directory - l: Event loop to associate the operation with, defaults to the current thread's loop
Returns: A non-nil pointer to the operation, alive until the callback is called
prep_poll
prep_poll :: proc(socket: Any_Socket, event: Poll_Event, cb: Callback, timeout: time.Duration, l: ^Event_Loop) -> (^Operation)SourceRetrieves and preps an operation to poll a socket without executing it.
Executing can then be done with the exec procedure.
The timeout is calculated from the time when this procedure was called, not from when it's executed.
Any user data can be set on the returned operation's user_data field.
Inputs:
- socket: Socket to poll that is associated with the event loop
- event: Event to poll for
- cb: The callback to be called when the operation finishes,
Operation.pollwill contain results - timeout: Optional timeout for the operation, the callback will receive a
.Timeoutresult after that duration - l: Event loop to associate the operation with, defaults to the current thread's loop
Returns: A non-nil pointer to the operation, alive until the callback is called
prep_read
prep_read :: proc(
handle: Handle,
offset: int,
buf: []u8,
cb: Callback,
all: untyped boolean = false,
timeout: time.Duration,
l: ^Event_Loop,
) -> (^Operation)SourceRetrieves and preps a positional read operation without executing it.
This is a pread-style operation: the read starts at the given offset and does not modify the handle's current file position.
Executing can then be done with the exec procedure.
The timeout is calculated from the time when this procedure was called, not from when it's executed.
Any user data can be set on the returned operation's user_data field.
Inputs:
- handle: Handle to read from
- offset: Offset to read from
- buf: Buffer to read data into (must not be empty)
- cb: The callback to be called when the operation finishes,
Operation.readwill contain results - all: Whether to read until the buffer is full or an error occurs
- timeout: Optional timeout for the operation
- l: Event loop to associate the operation with, defaults to the current thread's loop
Returns: A non-nil pointer to the operation, alive until the callback is called
prep_recv
prep_recv :: proc(
socket: Any_Socket,
bufs: [][]u8,
cb: Callback,
all: untyped boolean = false,
timeout: time.Duration,
l: ^Event_Loop,
) -> (^Operation)SourceRetrieves and preps an operation to do a receive without executing it.
Executing can then be done with the exec procedure.
To avoid ambiguity between a closed connection and a 0-byte read, the provided buffers must have a total capacity greater than 0.
The bufs slice itself is copied into the operation, so it can be temporary (e.g. on the stack), but the underlying memory of the buffers must remain valid until the callback is fired.
The timeout is calculated from the time when this procedure was called, not from when it's executed.
Any user data can be set on the returned operation's user_data field.
Inputs:
- socket: The socket to receive from
- bufs: Buffers to fill with received data
- cb: The callback to be called when the operation finishes,
Operation.recvwill contain results - all: If true, waits until all buffers are full before completing (TCP only, ignored for UDP)
- timeout: Optional timeout for the operation, the callback will get a
.Timeouterror after that duration - l: Event loop to associate the operation with, defaults to the current thread's loop
Returns: A non-nil pointer to the operation, alive until the callback is called
prep_send
prep_send :: proc(
socket: Any_Socket,
bufs: [][]u8,
cb: Callback,
endpoint: Endpoint,
all: untyped boolean = true,
timeout: time.Duration,
l: ^Event_Loop,
) -> (^Operation)SourceRetrieves and preps an operation to do a send without executing it.
Executing can then be done with the exec procedure.
The bufs slice itself is copied into the operation, so it can be temporary (e.g. on the stack), but the underlying memory of the buffers must remain valid until the callback is fired.
The timeout is calculated from the time when this procedure was called, not from when it's executed.
Any user data can be set on the returned operation's user_data field.
Inputs:
- socket: The socket to send to
- bufs: Buffers containing the data to send
- cb: The callback to be called when the operation finishes,
Operation.sendwill contain results - endpoint: The destination endpoint (UDP only, ignored for TCP)
- all: If true, the operation ensures all data is sent before completing
- timeout: Optional timeout for the operation, the callback will get a
.Timeouterror after that duration - l: Event loop to associate the operation with, defaults to the current thread's loop
Returns: A non-nil pointer to the operation, alive until the callback is called
prep_sendfile
prep_sendfile :: proc(
socket: TCP_Socket,
file: Handle,
cb: Callback,
offset: int,
nbytes: int,
progress_updates: untyped boolean = false,
timeout: time.Duration,
l: ^Event_Loop,
) -> (^Operation)SourceRetrieves and preps an operation to send a file over a socket without executing it.
Executing can then be done with the exec procedure.
This uses high-performance zero-copy system calls where available. Note: This is emulated on NetBSD and OpenBSD (stat -> mmap -> send) as they lack a native sendfile implementation.
Any user data can be set on the returned operation's user_data field.
Inputs:
- socket: The destination TCP socket
- file: The source file handle
- cb: The callback to be called when data is sent (if
progress_updatesis true) or the operation completes - offset: Byte offset to start reading from the file
- nbytes: Total bytes to send (use SEND_ENTIRE_FILE for the whole file)
- progress_updates: If true, the callback fires multiple times to report progress,
sent == nbytesmeans te operation completed - timeout: Optional timeout for the operation
- l: Event loop to associate the operation with, defaults to the current thread's loop
Returns: A non-nil pointer to the operation, alive until the final callback is called
prep_stat
prep_stat :: proc(handle: Handle, cb: Callback, l: ^Event_Loop) -> (^Operation)SourceRetrieves and preps an operation to stat a handle without executing it.
Executing can then be done with the exec procedure.
Any user data can be set on the returned operation's user_data field.
Inputs:
- handle: Handle to retrieve stat
- cb: The callback to be called when the operation finishes,
Operation.statwill contain results - l: Event loop to associate the operation with, defaults to the current thread's loop
Returns: A non-nil pointer to the operation, alive until the callback is called
prep_timeout
prep_timeout :: proc(duration: time.Duration, cb: Callback, l: ^Event_Loop) -> (^Operation)SourceRetrieves and preps a timeout operation without executing it.
Executing can then be done with the exec procedure.
Any user data can be set on the returned operation's user_data field.
Inputs:
- duration: Duration to wait before the operation completes
- cb: The callback to be called when the operation finishes
- l: Event loop to associate the operation with, defaults to the current thread's loop
Returns: A non-nil pointer to the operation, alive until the callback is called
prep_write
prep_write :: proc(
handle: Handle,
offset: int,
buf: []u8,
cb: Callback,
all: untyped boolean = true,
timeout: time.Duration,
l: ^Event_Loop,
) -> (^Operation)SourceRetrieves and preps a positional write operation without executing it.
This is a pwrite-style operation: the write starts at the given offset and does not modify the handle's current file position.
Executing can then be done with the exec procedure.
The timeout is calculated from the time when this procedure was called, not from when it's executed.
Any user data can be set on the returned operation's user_data field.
Inputs:
- handle: Handle to write to
- offset: Offset to write to
- buf: Buffer containing data to write (must not be empty)
- cb: The callback to be called when the operation finishes,
Operation.writewill contain results - all: Whether to write until the entire buffer is written or an error occurs
- timeout: Optional timeout for the operation
- l: Event loop to associate the operation with, defaults to the current thread's loop
Returns: A non-nil pointer to the operation, alive until the callback is called
read
read :: proc(
handle: Handle,
offset: int,
buf: []u8,
cb: Callback,
all: untyped boolean = false,
timeout: time.Duration,
l: ^Event_Loop,
) -> (^Operation)SourceReads data from a handle at a specific offset.
This is a pread-style operation: the read starts at the given offset and does not modify the handle's current file position.
Any user data can be set on the returned operation's user_data field. Polymorphic variants for type safe user data are available under read_poly, read_poly2, and read_poly3.
Inputs:
- handle: Handle to read from
- offset: Offset to read from
- buf: Buffer to read data into (must not be empty)
- cb: The callback to be called when the operation finishes,
Operation.readwill contain results - all: Whether to read until the buffer is full or an error occurs
- timeout: Optional timeout for the operation
- l: Event loop to associate the operation with, defaults to the current thread's loop
Returns: A non-nil pointer to the operation, alive until the callback is called
read_callback
read_callback :: proc(op: ^Operation, res: i32) -> (bool)Sourceread_entire_file
read_entire_file :: proc(
path: string,
user_data: rawptr,
cb: Read_Entire_File_Callback,
allocator: mem.Allocator = context.allocator,
dir: _ = CWD,
l: ^Event_Loop,
loc: _ = #caller_location,
)SourceCombines multiple operations (open, stat, read, close) into one that reads an entire regular file.
The error contains the operation that the error happened on.
Inputs:
- path: path to the file, if not absolute: relative from
dir - user_data: a pointer passed through into the callback
- cb: the callback to call once completed, called with the user data, file data, and an optional error
- allocator: the allocator to allocate the file's contents onto
- dir: directory that
pathis relative from (if it is relative), defaults to the current working directory - l: event loop to execute the operation on
read_exec
read_exec :: proc(op: ^Operation)Sourceread_poly
read_poly :: proc(
handle: Handle,
offset: int,
buf: []u8,
p: T,
cb: C,
all: untyped boolean = false,
timeout: time.Duration,
l: ^Event_Loop,
) -> (^Operation)SourceReads data from a handle at a specific offset.
This is a pread-style operation: the read starts at the given offset and does not modify the handle's current file position.
This procedure uses polymorphism for type safe user data up to a certain size.
Inputs:
- handle: Handle to read from
- offset: Offset to read from
- buf: Buffer to read data into (must not be empty)
- p: User data, the callback will receive this as its second argument
- cb: The callback to be called when the operation finishes,
Operation.readwill contain results - all: Whether to read until the buffer is full or an error occurs
- timeout: Optional timeout for the operation
- l: Event loop to associate the operation with, defaults to the current thread's loop
Returns: A non-nil pointer to the operation, alive until the callback is called
read_poly2
read_poly2 :: proc(
handle: Handle,
offset: int,
buf: []u8,
p: T,
p2: T2,
cb: C,
all: untyped boolean = false,
timeout: time.Duration,
l: ^Event_Loop,
) -> (^Operation)SourceReads data from a handle at a specific offset.
This is a pread-style operation: the read starts at the given offset and does not modify the handle's current file position.
This procedure uses polymorphism for type safe user data up to a certain size.
Inputs:
- handle: Handle to read from
- offset: Offset to read from
- buf: Buffer to read data into (must not be empty)
- p: User data, the callback will receive this as its second argument
- p2: User data, the callback will receive this as its third argument
- cb: The callback to be called when the operation finishes,
Operation.readwill contain results - all: Whether to read until the buffer is full or an error occurs
- timeout: Optional timeout for the operation
- l: Event loop to associate the operation with, defaults to the current thread's loop
Returns: A non-nil pointer to the operation, alive until the callback is called
read_poly3
read_poly3 :: proc(
handle: Handle,
offset: int,
buf: []u8,
p: T,
p2: T2,
p3: T3,
cb: C,
all: untyped boolean = false,
timeout: time.Duration,
l: ^Event_Loop,
) -> (^Operation)SourceReads data from a handle at a specific offset.
This is a pread-style operation: the read starts at the given offset and does not modify the handle's current file position.
This procedure uses polymorphism for type safe user data up to a certain size.
Inputs:
- handle: Handle to read from
- offset: Offset to read from
- buf: Buffer to read data into (must not be empty)
- p: User data, the callback will receive this as its second argument
- p2: User data, the callback will receive this as its third argument
- p3: User data, the callback will receive this as its fourth argument
- cb: The callback to be called when the operation finishes,
Operation.readwill contain results - all: Whether to read until the buffer is full or an error occurs
- timeout: Optional timeout for the operation
- l: Event loop to associate the operation with, defaults to the current thread's loop
Returns: A non-nil pointer to the operation, alive until the callback is called
reattach
reattach :: proc(op: ^Operation)SourceReattach an operation to the package's lifetime management.
recv
recv :: proc(
socket: Any_Socket,
bufs: [][]u8,
cb: Callback,
all: untyped boolean = false,
timeout: time.Duration,
l: ^Event_Loop,
) -> (^Operation)SourceReceives data from the socket.
If the operation completes with 0 bytes received and no error, it indicates the connection was closed by the peer.
The bufs slice itself is copied into the operation, so it can be temporary (e.g. on the stack), but the underlying memory of the buffers must remain valid until the callback is fired.
Any user data can be set on the returned operation's user_data field. Polymorphic variants for type safe user data are available under recv_poly, recv_poly2, and recv_poly3.
Inputs:
- socket: The socket to receive from
- bufs: Buffers to fill with received data
- cb: The callback to be called when the operation finishes,
Operation.recvwill contain results - all: If true, waits until all buffers are full before completing (TCP only, ignored for UDP)
- timeout: Optional timeout for the operation, the callback will get a
.Timeouterror after that duration - l: Event loop to associate the operation with, defaults to the current thread's loop
Returns: A non-nil pointer to the operation, alive until the callback is called
recv_callback
recv_callback :: proc(op: ^Operation, res: i32) -> (bool)Sourcerecv_exec
recv_exec :: proc(op: ^Operation)Sourcerecv_poly
recv_poly :: proc(
socket: Any_Socket,
bufs: [][]u8,
p: T,
cb: C,
all: untyped boolean = false,
timeout: time.Duration,
l: ^Event_Loop,
) -> (^Operation)SourceReceives data from the socket.
If the operation completes with 0 bytes received and no error, it indicates the connection was closed by the peer.
The bufs slice itself is copied into the operation, so it can be temporary (e.g. on the stack), but the underlying memory of the buffers must remain valid until the callback is fired.
This procedure uses polymorphism for type safe user data up to a certain size.
Inputs:
- socket: The socket to receive from
- bufs: Buffers to fill with received data
- p: User data, the callback will receive this as it's second argument
- cb: The callback to be called when the operation finishes,
Operation.recvwill contain results - all: If true, waits until all buffers are full before completing (TCP only, ignored for UDP)
- timeout: Optional timeout for the operation, the callback will get a
.Timeouterror after that duration - l: Event loop to associate the operation with, defaults to the current thread's loop
Returns: A non-nil pointer to the operation, alive until the callback is called
recv_poly2
recv_poly2 :: proc(
socket: Any_Socket,
bufs: [][]u8,
p: T,
p2: T2,
cb: C,
all: untyped boolean = false,
timeout: time.Duration,
l: ^Event_Loop,
) -> (^Operation)SourceReceives data from the socket.
If the operation completes with 0 bytes received and no error, it indicates the connection was closed by the peer.
The bufs slice itself is copied into the operation, so it can be temporary (e.g. on the stack), but the underlying memory of the buffers must remain valid until the callback is fired.
This procedure uses polymorphism for type safe user data up to a certain size.
Inputs:
- socket: The socket to receive from
- bufs: Buffers to fill with received data
- p: User data, the callback will receive this as it's second argument
- p2: User data, the callback will receive this as it's third argument
- cb: The callback to be called when the operation finishes,
Operation.recvwill contain results - all: If true, waits until all buffers are full before completing (TCP only, ignored for UDP)
- timeout: Optional timeout for the operation, the callback will get a
.Timeouterror after that duration - l: Event loop to associate the operation with, defaults to the current thread's loop
Returns: A non-nil pointer to the operation, alive until the callback is called
recv_poly3
recv_poly3 :: proc(
socket: Any_Socket,
bufs: [][]u8,
p: T,
p2: T2,
p3: T3,
cb: C,
all: untyped boolean = false,
timeout: time.Duration,
l: ^Event_Loop,
) -> (^Operation)SourceReceives data from the socket.
If the operation completes with 0 bytes received and no error, it indicates the connection was closed by the peer.
The bufs slice itself is copied into the operation, so it can be temporary (e.g. on the stack), but the underlying memory of the buffers must remain valid until the callback is fired.
This procedure uses polymorphism for type safe user data up to a certain size.
Inputs:
- socket: The socket to receive from
- bufs: Buffers to fill with received data
- p: User data, the callback will receive this as it's second argument
- p2: User data, the callback will receive this as it's third argument
- p3: User data, the callback will receive this as it's fourth argument
- cb: The callback to be called when the operation finishes,
Operation.recvwill contain results - all: If true, waits until all buffers are full before completing (TCP only, ignored for UDP)
- timeout: Optional timeout for the operation, the callback will get a
.Timeouterror after that duration - l: Event loop to associate the operation with, defaults to the current thread's loop
Returns: A non-nil pointer to the operation, alive until the callback is called
release_thread_event_loop
release_thread_event_loop :: proc()SourceDestroy or decrease the reference counted event loop for the current thread.
remove
remove :: proc(target: ^Operation)SourceRemove the given operation from the event loop. The callback of it won't be called and resources are freed.
Calling remove:
- Cancels the operation if it has not yet completed
- Prevents the callback from being called
Cancellation via remove is final and silent:
- The callback will never be invoked
- No error is delivered
- The operation must be considered dead after removal
WARN: the operation could have already been (partially or completely) completed.
A send with `all` set to true could have sent a portion already.
But also, a send that could be completed without blocking could have been completed.
You just won't get a callback.
WARN: once an operation's callback is called it can not be removed anymore (use after free).
WARN: needs to be called from the thread of the event loop the target belongs to.
Common use would be to cancel a timeout, remove a polling, or remove an `accept` before calling `close` on it's socket.remove_callback
remove_callback :: proc(op: ^Operation, res: i32) -> (bool)Sourcerun
run :: proc() -> (General_Error)SourceRuns the event loop by ticking in a loop until there is no more work to be done.
run_until
run_until :: proc(done: ^bool) -> (General_Error)SourceRuns the event loop by ticking in a loop until there is no more work to be done, or the flag done is true.
send
send :: proc(
socket: Any_Socket,
bufs: [][]u8,
cb: Callback,
endpoint: Endpoint,
all: untyped boolean = true,
timeout: time.Duration,
l: ^Event_Loop,
) -> (^Operation)SourceSends data to the socket.
The bufs slice itself is copied into the operation, so it can be temporary (e.g. on the stack), but the underlying memory of the buffers must remain valid until the callback is fired.
Any user data can be set on the returned operation's user_data field. Polymorphic variants for type safe user data are available under send_poly, send_poly2, and send_poly3.
Inputs:
- socket: The socket to send to
- bufs: Buffers containing the data to send
- cb: The callback to be called when the operation finishes,
Operation.sendwill contain results - endpoint: The destination endpoint (UDP only, ignored for TCP)
- all: If true, the operation ensures all data is sent before completing
- timeout: Optional timeout for the operation, the callback will get a
.Timeouterror after that duration - l: Event loop to associate the operation with, defaults to the current thread's loop
Returns: A non-nil pointer to the operation, alive until the callback is called
send_callback
send_callback :: proc(op: ^Operation, res: i32) -> (bool)Sourcesend_exec
send_exec :: proc(op: ^Operation)Sourcesend_poly
send_poly :: proc(
socket: Any_Socket,
bufs: [][]u8,
p: T,
cb: C,
endpoint: Endpoint,
all: untyped boolean = true,
timeout: time.Duration,
l: ^Event_Loop,
) -> (^Operation)SourceSends data to the socket.
The bufs slice itself is copied into the operation, so it can be temporary (e.g. on the stack), but the underlying memory of the buffers must remain valid until the callback is fired.
This procedure uses polymorphism for type safe user data up to a certain size.
Inputs:
- socket: The socket to send to
- bufs: Buffers containing the data to send
- p: User data, the callback will receive this as it's second argument
- cb: The callback to be called when the operation finishes,
Operation.sendwill contain results - endpoint: The destination endpoint (UDP only, ignored for TCP)
- all: If true, the operation ensures all data is sent before completing
- timeout: Optional timeout for the operation, the callback will get a
.Timeouterror after that duration - l: Event loop to associate the operation with, defaults to the current thread's loop
Returns: A non-nil pointer to the operation, alive until the callback is called
send_poly2
send_poly2 :: proc(
socket: Any_Socket,
bufs: [][]u8,
p: T,
p2: T2,
cb: C,
endpoint: Endpoint,
all: untyped boolean = true,
timeout: time.Duration,
l: ^Event_Loop,
) -> (^Operation)SourceSends data to the socket.
The bufs slice itself is copied into the operation, so it can be temporary (e.g. on the stack), but the underlying memory of the buffers must remain valid until the callback is fired.
This procedure uses polymorphism for type safe user data up to a certain size.
Inputs:
- socket: The socket to send to
- bufs: Buffers containing the data to send
- p: User data, the callback will receive this as it's second argument
- p2: User data, the callback will receive this as it's third argument
- cb: The callback to be called when the operation finishes,
Operation.sendwill contain results - endpoint: The destination endpoint (UDP only, ignored for TCP)
- all: If true, the operation ensures all data is sent before completing
- timeout: Optional timeout for the operation, the callback will get a
.Timeouterror after that duration - l: Event loop to associate the operation with, defaults to the current thread's loop
Returns: A non-nil pointer to the operation, alive until the callback is called
send_poly3
send_poly3 :: proc(
socket: Any_Socket,
bufs: [][]u8,
p: T,
p2: T2,
p3: T3,
cb: C,
endpoint: Endpoint,
all: untyped boolean = true,
timeout: time.Duration,
l: ^Event_Loop,
) -> (^Operation)SourceSends data to the socket.
The bufs slice itself is copied into the operation, so it can be temporary (e.g. on the stack), but the underlying memory of the buffers must remain valid until the callback is fired.
This procedure uses polymorphism for type safe user data up to a certain size.
Inputs:
- socket: The socket to send to
- bufs: Buffers containing the data to send
- p: User data, the callback will receive this as it's second argument
- p2: User data, the callback will receive this as it's third argument
- p3: User data, the callback will receive this as it's fourth argument
- cb: The callback to be called when the operation finishes,
Operation.sendwill contain results - endpoint: The destination endpoint (UDP only, ignored for TCP)
- all: If true, the operation ensures all data is sent before completing
- timeout: Optional timeout for the operation, the callback will get a
.Timeouterror after that duration - l: Event loop to associate the operation with, defaults to the current thread's loop
Returns: A non-nil pointer to the operation, alive until the callback is called
sendfile
sendfile :: proc(
socket: TCP_Socket,
file: Handle,
cb: Callback,
offset: int,
nbytes: int,
progress_updates: untyped boolean = false,
timeout: time.Duration,
l: ^Event_Loop,
) -> (^Operation)SourceSends a file over a TCP socket.
This uses high-performance zero-copy system calls where available. Note: This is emulated on NetBSD and OpenBSD (stat -> mmap -> send) as they lack a native sendfile implementation.
Any user data can be set on the returned operation's user_data field. Polymorphic variants for type safe user data are available under sendfile_poly, sendfile_poly2, and sendfile_poly3.
Inputs:
- socket: The destination TCP socket
- file: The source file handle
- cb: The callback to be called when data is sent (if
progress_updatesis true) or the operation completes - offset: Byte offset to start reading from the file
- nbytes: Total bytes to send (use SEND_ENTIRE_FILE for the whole file)
- progress_updates: If true, the callback fires multiple times to report progress,
sent == nbytesmeans te operation completed - timeout: Optional timeout for the operation
- l: Event loop to associate the operation with, defaults to the current thread's loop
Returns: A non-nil pointer to the operation, alive until the final callback is called
sendfile_callback
sendfile_callback :: proc(op: ^Operation, res: i32) -> (bool)Sourcesendfile_exec
sendfile_exec :: proc(op: ^Operation, splice: untyped boolean = true)Sourcesendfile is implemented with 2 splices over a pipe.
Splice A: from file to pipe Splice B: from pipe to socket (optionally linked to a timeout)
The splices are hard-linked which means A completes before B. B could get an EWOULDBLOCK, which is when the remote end has not read enough of the socket data yet. In that case we enqueue a poll on the socket and continue when that completes. A shouldn't get EWOULDBLOCK, but as a cautionary measure we handle it.
The timeout is either linked to the splice B op, or the poll op, either of these is also always in progress in the kernel.
sendfile_poly
sendfile_poly :: proc(
socket: TCP_Socket,
file: Handle,
p: T,
cb: C,
offset: int,
nbytes: int,
progress_updates: untyped boolean = false,
timeout: time.Duration,
l: ^Event_Loop,
) -> (^Operation)SourceSends a file over a TCP socket.
This uses high-performance zero-copy system calls where available. Note: This is emulated on NetBSD and OpenBSD (stat -> mmap -> send) as they lack a native sendfile implementation.
This procedure uses polymorphism for type safe user data up to a certain size.
Inputs:
- socket: The destination TCP socket
- file: The source file handle
- p: User data, the callback will receive this as it's second argument
- cb: The callback to be called when data is sent (if
progress_updatesis true) or the operation completes - offset: Byte offset to start reading from the file
- nbytes: Total bytes to send (use SEND_ENTIRE_FILE for the whole file)
- progress_updates: If true, the callback fires multiple times to report progress,
sent == nbytesmeans te operation completed - timeout: Optional timeout for the operation
- l: Event loop to associate the operation with, defaults to the current thread's loop
Returns: A non-nil pointer to the operation, alive until the final callback is called
sendfile_poly2
sendfile_poly2 :: proc(
socket: TCP_Socket,
file: Handle,
p: T,
p2: T2,
cb: C,
offset: int,
nbytes: int,
progress_updates: untyped boolean = false,
timeout: time.Duration,
l: ^Event_Loop,
) -> (^Operation)SourceSends a file over a TCP socket.
This uses high-performance zero-copy system calls where available. Note: This is emulated on NetBSD and OpenBSD (stat -> mmap -> send) as they lack a native sendfile implementation.
This procedure uses polymorphism for type safe user data up to a certain size.
Inputs:
- socket: The destination TCP socket
- file: The source file handle
- p: User data, the callback will receive this as it's second argument
- p2: User data, the callback will receive this as it's third argument
- cb: The callback to be called when data is sent (if
progress_updatesis true) or the operation completes - offset: Byte offset to start reading from the file
- nbytes: Total bytes to send (use SEND_ENTIRE_FILE for the whole file)
- progress_updates: If true, the callback fires multiple times to report progress,
sent == nbytesmeans te operation completed - timeout: Optional timeout for the operation
- l: Event loop to associate the operation with, defaults to the current thread's loop
Returns: A non-nil pointer to the operation, alive until the final callback is called
sendfile_poly3
sendfile_poly3 :: proc(
socket: TCP_Socket,
file: Handle,
p: T,
p2: T2,
p3: T3,
cb: C,
offset: int,
nbytes: int,
progress_updates: untyped boolean = false,
timeout: time.Duration,
l: ^Event_Loop,
) -> (^Operation)SourceSends a file over a TCP socket.
This uses high-performance zero-copy system calls where available. Note: This is emulated on NetBSD and OpenBSD (stat -> mmap -> send) as they lack a native sendfile implementation.
This procedure uses polymorphism for type safe user data up to a certain size.
Inputs:
- socket: The destination TCP socket
- file: The source file handle
- p: User data, the callback will receive this as it's second argument
- p2: User data, the callback will receive this as it's third argument
- p3: User data, the callback will receive this as it's fourth argument
- cb: The callback to be called when data is sent (if
progress_updatesis true) or the operation completes - offset: Byte offset to start reading from the file
- nbytes: Total bytes to send (use SEND_ENTIRE_FILE for the whole file)
- progress_updates: If true, the callback fires multiple times to report progress,
sent == nbytesmeans te operation completed - timeout: Optional timeout for the operation
- l: Event loop to associate the operation with, defaults to the current thread's loop
Returns: A non-nil pointer to the operation, alive until the final callback is called
sockaddr_storage_to_endpoint_any
sockaddr_storage_to_endpoint_any :: proc(addr: ^linux.Sock_Addr_Any) -> (ep: Endpoint)Sourcesockaddr_storage_to_endpoint_ip
sockaddr_storage_to_endpoint_ip :: proc(addr: ^Sock_Addr_Ip) -> (ep: Endpoint)Sourcesplice_callback
splice_callback :: proc(op: ^Operation, res: i32) -> (bool)Sourcestat
stat :: proc(handle: Handle, cb: Callback, l: ^Event_Loop) -> (^Operation)SourceStats a handle.
Any user data can be set on the returned operation's user_data field. Polymorphic variants for type safe user data are available under stat_poly, stat_poly2, and stat_poly3.
Inputs:
- handle: Handle to retrieve status information for
- cb: The callback to be called when the operation finishes,
Operation.statwill contain results - l: Event loop to associate the operation with, defaults to the current thread's loop
Returns: A non-nil pointer to the operation, alive until the callback is called
stat_callback
stat_callback :: proc(op: ^Operation, res: i32)Sourcestat_exec
stat_exec :: proc(op: ^Operation)Sourcestat_poly
stat_poly :: proc(handle: Handle, p: T, cb: C, l: ^Event_Loop) -> (^Operation)SourceStats a handle.
This procedure uses polymorphism for type safe user data up to a certain size.
Inputs:
- handle: Handle to retrieve status information for
- p: User data, the callback will receive this as its second argument
- cb: The callback to be called when the operation finishes,
Operation.statwill contain results - l: Event loop to associate the operation with, defaults to the current thread's loop
Returns: A non-nil pointer to the operation, alive until the callback is called
stat_poly2
stat_poly2 :: proc(handle: Handle, p: T, p2: T2, cb: C, l: ^Event_Loop) -> (^Operation)SourceStats a handle.
This procedure uses polymorphism for type safe user data up to a certain size.
Inputs:
- handle: Handle to retrieve status information for
- p: User data, the callback will receive this as its second argument
- p2: User data, the callback will receive this as its third argument
- cb: The callback to be called when the operation finishes,
Operation.statwill contain results - l: Event loop to associate the operation with, defaults to the current thread's loop
Returns: A non-nil pointer to the operation, alive until the callback is called
stat_poly3
stat_poly3 :: proc(
handle: Handle,
p: T,
p2: T2,
p3: T3,
cb: C,
l: ^Event_Loop,
) -> (^Operation)SourceStats a handle.
This procedure uses polymorphism for type safe user data up to a certain size.
Inputs:
- handle: Handle to retrieve status information for
- p: User data, the callback will receive this as its second argument
- p2: User data, the callback will receive this as its third argument
- p3: User data, the callback will receive this as its fourth argument
- cb: The callback to be called when the operation finishes,
Operation.statwill contain results - l: Event loop to associate the operation with, defaults to the current thread's loop
Returns: A non-nil pointer to the operation, alive until the callback is called
tick
tick :: proc(timeout: time.Duration) -> (General_Error)SourceEach time you call this the implementation checks its state and calls any callbacks which are ready. You would typically call this in a loop.
Blocks for up-to timeout waiting for events if there is nothing to do.
timeout
timeout :: proc(duration: time.Duration, cb: Callback, l: ^Event_Loop) -> (^Operation)SourceSchedules a timeout that completes after the given duration.
Any user data can be set on the returned operation's user_data field. Polymorphic variants for type safe user data are available under timeout_poly, timeout_poly2, and timeout_poly3.
Inputs:
- duration: Duration to wait before the operation completes
- cb: The callback to be called when the operation finishes
- l: Event loop to associate the operation with, defaults to the current thread's loop
Returns: A non-nil pointer to the operation, alive until the callback is called
timeout_callback
timeout_callback :: proc(op: ^Operation, res: i32)Sourcetimeout_exec
timeout_exec :: proc(op: ^Operation)Sourcetimeout_poly
timeout_poly :: proc(dur: time.Duration, p: T, cb: C, l: ^Event_Loop) -> (^Operation)SourceSchedules a timeout that completes after the given duration.
This procedure uses polymorphism for type safe user data up to a certain size.
Inputs:
- dur: Duration to wait before the operation completes
- p: User data, the callback will receive this as its second argument
- cb: The callback to be called when the operation finishes
- l: Event loop to associate the operation with, defaults to the current thread's loop
Returns: A non-nil pointer to the operation, alive until the callback is called
timeout_poly2
timeout_poly2 :: proc(dur: time.Duration, p: T, p2: T2, cb: C, l: ^Event_Loop) -> (^Operation)SourceSchedules a timeout that completes after the given duration.
This procedure uses polymorphism for type safe user data up to a certain size.
Inputs:
- dur: Duration to wait before the operation completes
- p: User data, the callback will receive this as its second argument
- p2: User data, the callback will receive this as its third argument
- cb: The callback to be called when the operation finishes
- l: Event loop to associate the operation with, defaults to the current thread's loop
Returns: A non-nil pointer to the operation, alive until the callback is called
timeout_poly3
timeout_poly3 :: proc(
dur: time.Duration,
p: T,
p2: T2,
p3: T3,
cb: C,
l: ^Event_Loop,
) -> (^Operation)SourceSchedules a timeout that completes after the given duration.
This procedure uses polymorphism for type safe user data up to a certain size.
Inputs:
- dur: Duration to wait before the operation completes
- p: User data, the callback will receive this as its second argument
- p2: User data, the callback will receive this as its third argument
- p3: User data, the callback will receive this as its fourth argument
- cb: The callback to be called when the operation finishes
- l: Event loop to associate the operation with, defaults to the current thread's loop
Returns: A non-nil pointer to the operation, alive until the callback is called
unpack_operation
unpack_operation :: proc(user_data: u64) -> (op: ^Operation, timed_out: bool)Sourcewake_up
wake_up :: proc(l: ^Event_Loop)SourceWake up an event loop on another thread which may be blocking for completed operations.
Commonly used with exec from a worker thread to have the event loop pick up that work. Note that by default exec already calls this procedure.
warn
warn :: proc(text: string, location = #caller_location)Sourcewrite
write :: proc(
handle: Handle,
offset: int,
buf: []u8,
cb: Callback,
all: untyped boolean = true,
timeout: time.Duration,
l: ^Event_Loop,
) -> (^Operation)SourceWrites data to a handle at a specific offset.
This is a pwrite-style operation: the write starts at the given offset and does not modify the handle's current file position.
Any user data can be set on the returned operation's user_data field. Polymorphic variants for type safe user data are available under write_poly, write_poly2, and write_poly3.
Inputs:
- handle: Handle to write to
- offset: Offset to write to
- buf: Buffer containing data to write (must not be empty)
- cb: The callback to be called when the operation finishes,
Operation.writewill contain results - all: Whether to write until the entire buffer is written or an error occurs
- timeout: Optional timeout for the operation
- l: Event loop to associate the operation with, defaults to the current thread's loop
Returns: A non-nil pointer to the operation, alive until the callback is called
write_callback
write_callback :: proc(op: ^Operation, res: i32) -> (bool)Sourcewrite_exec
write_exec :: proc(op: ^Operation)Sourcewrite_poly
write_poly :: proc(
handle: Handle,
offset: int,
buf: []u8,
p: T,
cb: C,
all: untyped boolean = true,
timeout: time.Duration,
l: ^Event_Loop,
) -> (^Operation)SourceWrites data to a handle at a specific offset.
This is a pwrite-style operation: the write starts at the given offset and does not modify the handle's current file position.
This procedure uses polymorphism for type safe user data up to a certain size.
Inputs:
- handle: Handle to write to
- offset: Offset to write to
- buf: Buffer containing data to write (must not be empty)
- p: User data, the callback will receive this as its second argument
- cb: The callback to be called when the operation finishes,
Operation.writewill contain results - all: Whether to write until the entire buffer is written or an error occurs
- timeout: Optional timeout for the operation
- l: Event loop to associate the operation with, defaults to the current thread's loop
Returns: A non-nil pointer to the operation, alive until the callback is called
write_poly2
write_poly2 :: proc(
handle: Handle,
offset: int,
buf: []u8,
p: T,
p2: T2,
cb: C,
all: untyped boolean = true,
timeout: time.Duration,
l: ^Event_Loop,
) -> (^Operation)SourceWrites data to a handle at a specific offset.
This is a pwrite-style operation: the write starts at the given offset and does not modify the handle's current file position.
This procedure uses polymorphism for type safe user data up to a certain size.
Inputs:
- handle: Handle to write to
- offset: Offset to write to
- buf: Buffer containing data to write (must not be empty)
- p: User data, the callback will receive this as its second argument
- p2: User data, the callback will receive this as its third argument
- cb: The callback to be called when the operation finishes,
Operation.writewill contain results - all: Whether to write until the entire buffer is written or an error occurs
- timeout: Optional timeout for the operation
- l: Event loop to associate the operation with, defaults to the current thread's loop
Returns: A non-nil pointer to the operation, alive until the callback is called
write_poly3
write_poly3 :: proc(
handle: Handle,
offset: int,
buf: []u8,
p: T,
p2: T2,
p3: T3,
cb: C,
all: untyped boolean = true,
timeout: time.Duration,
l: ^Event_Loop,
) -> (^Operation)SourceWrites data to a handle at a specific offset.
This is a pwrite-style operation: the write starts at the given offset and does not modify the handle's current file position.
This procedure uses polymorphism for type safe user data up to a certain size.
Inputs:
- handle: Handle to write to
- offset: Offset to write to
- buf: Buffer containing data to write (must not be empty)
- p: User data, the callback will receive this as its second argument
- p2: User data, the callback will receive this as its third argument
- p3: User data, the callback will receive this as its fourth argument
- cb: The callback to be called when the operation finishes,
Operation.writewill contain results - all: Whether to write until the entire buffer is written or an error occurs
- timeout: Optional timeout for the operation
- l: Event loop to associate the operation with, defaults to the current thread's loop
Returns: A non-nil pointer to the operation, alive until the callback is called