package http:nbio

⌘K
Ctrl+K
or
/

    Overview

    package nbio implements a non blocking IO abstraction layer over several platform specific APIs.

    This package implements an event loop based abstraction.

    APIs: Windows: IOCP IO Completion Ports Linux: io_uring Darwin: KQueue

    How to read the code:

    The file nbio.odin can be read a little bit like a header file, it has all the procedures heavily explained and commented and dispatches them to platform specific code.

    You can also have a look at the tests for more general usages.

    Example:
    /*
    This example shows a simple TCP server that echos back anything it receives.
    
    Better error handling and closing/freeing connections are left for the reader.
    */
    package main
    
    import "core:fmt"
    import "core:net"
    import "core:os"
    
    import nbio "nbio/poly"
    
    Echo_Server :: struct {
    	io:          nbio.IO,
    	sock:        net.TCP_Socket,
    	connections: [dynamic]^Echo_Connection,
    }
    
    Echo_Connection :: struct {
    	server:  ^Echo_Server,
    	sock:    net.TCP_Socket,
    	buf:     [50]byte,
    }
    
    main :: proc() {
    	server: Echo_Server
    	defer delete(server.connections)
    
    	nbio.init(&server.io)
    	defer nbio.destroy(&server.io)
    
    	sock, err := nbio.open_and_listen_tcp(&server.io, {net.IP4_Loopback, 8080})
    	fmt.assertf(err == nil, "Error opening and listening on localhost:8080: %v", err)
    	server.sock = sock
    
    	nbio.accept(&server.io, sock, &server, echo_on_accept)
    
    	// Start the event loop.
    	errno: os.Errno
    	for errno == os.ERROR_NONE {
    		errno = nbio.tick(&server.io)
    	}
    
    	fmt.assertf(errno == os.ERROR_NONE, "Server stopped with error code: %v", errno)
    }
    
    echo_on_accept :: proc(server: ^Echo_Server, client: net.TCP_Socket, source: net.Endpoint, err: net.Network_Error) {
    	fmt.assertf(err == nil, "Error accepting a connection: %v", err)
    
    	// Register a new accept for the next client.
    	nbio.accept(&server.io, server.sock, server, echo_on_accept)
    
    	c := new(Echo_Connection)
    	c.server = server
    	c.sock   = client
    	append(&server.connections, c)
    
    	nbio.recv(&server.io, client, c.buf[:], c, echo_on_recv)
    }
    
    echo_on_recv :: proc(c: ^Echo_Connection, received: int, _: Maybe(net.Endpoint), err: net.Network_Error) {
    	fmt.assertf(err == nil, "Error receiving from client: %v", err)
    
    	nbio.send_all(&c.server.io, c.sock, c.buf[:received], c, echo_on_sent)
    }
    
    echo_on_sent :: proc(c: ^Echo_Connection, sent: int, err: net.Network_Error) {
    	fmt.assertf(err == nil, "Error sending to client: %v", err)
    
    	// Accept the next message, to then ultimately echo back again.
    	nbio.recv(&c.server.io, c.sock, c.buf[:], c, echo_on_recv)
    }
    

    Types

    Closable ¶

    Closable :: union #no_nil {
    	net.TCP_Socket, 
    	net.UDP_Socket, 
    	net.Socket, 
    	os.Handle, 
    }
     

    A union of types that are close'able by this package

    Related Procedures With Parameters

    Completion ¶

    Completion :: struct {
    	// Implementation specifics, don't use outside of implementation/os.
    	using _:   _Completion,
    	user_data: rawptr,
    	// Callback pointer and user args passed in poly variants.
    	user_args: [48]u8,
    }
    Related Procedures With Returns

    IO ¶

    IO :: _IO
     

    The main IO type that holds the platform dependant implementation state passed around most procedures in this package

    On_Accept ¶

    On_Accept :: proc(user: rawptr, client: net.TCP_Socket, source: net.Endpoint, err: net.Network_Error)
     

    The callback for non blocking accept requests

    Inputs:
    user: A passed through pointer from initiation to its callback client: The socket to communicate through with the newly accepted client source: The origin of the client err: A network error that occured during the accept process

    Related Procedures With Parameters

    On_Close ¶

    On_Close :: proc(user: rawptr, ok: bool)
     

    The callback for non blocking close requests

    Inputs:
    user: A passed through pointer from initiation to its callback ok: Whether the operation suceeded sucessfully

    Related Procedures With Parameters

    On_Connect ¶

    On_Connect :: proc(user: rawptr, socket: net.TCP_Socket, err: net.Network_Error)
     

    The callback for non blocking connect requests

    Inputs:
    user: A passed through pointer from initiation to its callback socket: A socket that is connected to the given endpoint in the connect call err: A network error that occured during the connect call

    Related Procedures With Parameters

    On_Next_Tick ¶

    On_Next_Tick :: proc(user: rawptr)
     

    The callback for a "next tick" event

    Inputs:
    user: A passed through pointer from initiation to its callback

    Related Procedures With Parameters

    On_Poll ¶

    On_Poll :: proc(user: rawptr, event: Poll_Event)
     

    The callback for poll requests

    Inputs:
    user: A passed through pointer from initiation to its callback event: The event that is ready to go

    Related Procedures With Parameters

    On_Read ¶

    On_Read :: proc(user: rawptr, read: int, err: os.Error)
     

    The callback for non blocking read or read_at requests

    Inputs:
    user: A passed through pointer from initiation to its callback read: The amount of bytes that were read and added to the given buf err: An error number if an error occured, 0 otherwise

    Related Procedures With Parameters

    On_Recv ¶

    On_Recv :: proc(user: rawptr, received: int, udp_client: runtime.Maybe($T=Endpoint), err: net.Network_Error)
     

    The callback for non blocking recv requests

    Inputs:
    user: A passed through pointer from initiation to its callback received: The amount of bytes that were read and added to the given buf udp_client: If the given socket was a net.UDP_Socket, this will be the client that was received from err: A network error if it occured

    Related Procedures With Parameters

    On_Sent ¶

    On_Sent :: proc(user: rawptr, sent: int, err: net.Network_Error)
     

    The callback for non blocking send and send_all requests

    Inputs:
    user: A passed through pointer from initiation to its callback sent: The amount of bytes that were sent over the connection err: A network error if it occured

    Related Procedures With Parameters

    On_Timeout ¶

    On_Timeout :: proc(user: rawptr)
     

    The callback for non blocking timeout calls

    Inputs:
    user: A passed through pointer from initiation to its callback

    Related Procedures With Parameters

    On_Write ¶

    On_Write :: proc(user: rawptr, written: int, err: os.Error)
     

    The callback for non blocking write, write_all, write_at and write_at_all requests

    Inputs:
    user: A passed through pointer from initiation to its callback written: The amount of bytes that were written to the file err: An error number if an error occured, 0 otherwise

    Related Procedures With Parameters

    Poll_Event ¶

    Poll_Event :: enum int {
    	// The subject is ready to be read from.
    	Read, 
    	// The subject is ready to be written to.
    	Write, 
    }
    Related Procedures With Parameters

    Whence ¶

    Whence :: enum int {
    	Set, 
    	Curr, 
    	End, 
    }
     

    Where to seek from

    Options: Set: sets the offset to the given value Curr: adds the given offset to the current offset End: adds the given offset to the end of the file

    Related Procedures With Parameters

    Constants

    MAX_USER_ARGUMENTS ¶

    MAX_USER_ARGUMENTS :: size_of(rawptr) * 5

    Variables

    This section is empty.

    Procedures

    accept ¶

    accept :: proc(io: ^_IO, socket: net.TCP_Socket, user: rawptr, callback: On_Accept) {…}
     

    Using the given socket, accepts the next incoming connection, calling the callback when that happens

    Due to platform limitations, you must pass a socket that was opened using the `open_socket` and related procedures from this package

    Inputs:
    io: The IO instance to use socket: A bound and listening socket that was created using this package user: A pointer that will be passed through to the callback, free to use by you and untouched by us callback: The callback that is called when the operation completes, see docs for On_Accept for its arguments

    close ¶

    close :: proc(io: ^_IO, fd: Closable, user: rawptr = nil, callback: On_Close = empty_on_close) {…}
     

    Closes the given Closable socket or file handle that was originally created by this package.

    Due to platform limitations, you must pass a `Closable` that was opened/returned using/by this package

    Inputs:
    io: The IO instance to use fd: The Closable socket or handle (created using/by this package) to close user: An optional pointer that will be passed through to the callback, free to use by you and untouched by us callback: An optional callback that is called when the operation completes, see docs for On_Close for its arguments

    connect ¶

    connect :: proc(io: ^_IO, endpoint: net.Endpoint, user: rawptr, callback: On_Connect) {…}
     

    Connects to the given endpoint, calling the given callback once it has been done

    Inputs:
    io: The IO instance to use endpoint: An endpoint to connect a socket to user: A pointer that will be passed through to the callback, free to use by you and untouched by us callback: The callback that is called when the operation completes, see docs for On_Connect for its arguments

    destroy ¶

    destroy :: proc(io: ^_IO) {…}
     

    Deallocates anything that was allocated when calling init()

    Inputs:
    io: The IO instance to deallocate

    Deallocates with the allocator that was passed with the init() call

    init ¶

    init :: proc(io: ^_IO, allocator := context.allocator) -> (err: os.Error) {…}
     

    Initializes the IO type, allocates different things per platform needs

    Allocates Using Provided Allocator

    Inputs:
    io: The IO struct to initialize allocator: (default: context.allocator)

    Returns:
    err: An error code when something went wrong with the setup of the platform's IO API, 0 otherwise

    listen ¶

    listen :: proc(socket: net.TCP_Socket, backlog: int = 1000) -> (err: net.Network_Error) {…}
     

    Starts listening on the given socket

    Inputs:
    socket: The socket to start listening backlog: The amount of events to keep in the backlog when they are not consumed

    Returns:
    err: A network error that happened when starting listening

    next_tick ¶

    next_tick :: proc(io: ^_IO, user: rawptr, callback: On_Next_Tick) -> ^Completion {…}
     

    Schedules a callback to be called during the next tick of the event loop.

    Inputs:
    io: The IO instance to use user: A pointer that will be passed through to the callback, free to use by you and untouched by us

    num_waiting ¶

    num_waiting :: proc(io: ^_IO) -> int {…}
     

    Returns the number of in-progress IO to be completed.

    open ¶

    open :: proc(io: ^_IO, path: string, mode: int = os.O_RDONLY, perm: int = 0) -> (handle: os.Handle, err: os.Error) {…}
     

    Opens a file hande, sets non blocking mode and relates it to the given IO

    The perm argument is only used when on the darwin or linux platforms, when on Windows you can't use the os.S_\ constants because they aren't declared* To prevent compilation errors on Windows, you should use a `when` statement around using those constants and just pass 0

    Inputs:
    io: The IO instance to connect the opened file to mode: The file mode (default: os.O_RDONLY) perm: The permissions to use when creating a file (default: 0)

    Returns:
    handle: The file handle err: The error code when an error occured, 0 otherwise

    open_and_listen_tcp ¶

    open_and_listen_tcp :: proc(io: ^_IO, ep: net.Endpoint) -> (socket: net.TCP_Socket, err: net.Network_Error) {…}
     

    Creates a socket, sets non blocking mode, relates it to the given IO, binds the socket to the given endpoint and starts listening

    Inputs:
    io: The IO instance to initialize the socket on/with endpoint: Where to bind the socket to

    Returns:
    socket: The opened, bound and listening socket err: A network error that happened while opening

    open_socket ¶

    open_socket :: proc(io: ^_IO, family: net.Address_Family, protocol: net.Socket_Protocol) -> (socket: net.Any_Socket, err: net.Network_Error) {…}
     

    Creates a socket, sets non blocking mode and relates it to the given IO

    Inputs:
    io: The IO instance to initialize the socket on/with family: Should this be an IP4 or IP6 socket protocol: The type of socket (TCP or UDP)

    Returns:
    socket: The opened socket err: A network error that happened while opening

    poll ¶

    poll :: proc(
    	io:       ^_IO, 
    	fd:       os.Handle, 
    	event:    Poll_Event, 
    	multi:    bool, 
    	user:     rawptr, 
    	callback: On_Poll, 
    ) {…}
     

    Polls for the given event on the subject handle

    Inputs:
    io: The IO instance to use fd: The file descriptor to poll event: Whether to call the callback when fd is ready to be read from, or be written to multi: Keeps the poll after an event happens, calling the callback again for further events, remove poll with poll_remove user: An optional pointer that will be passed through to the callback, free to use by you and untouched by us callback: The callback that is called when the operation completes, see docs for On_Poll for its arguments

    poll_remove ¶

    poll_remove :: proc(io: ^_IO, fd: os.Handle, event: Poll_Event) {…}
     

    Removes the polling for this subject+event pairing

    This is only needed when poll was called with multi set to true

    Inputs:
    io: The IO instance to use fd: The file descriptor to remove the poll of event: The event to remove the poll of

    read ¶

    read :: proc(io: ^_IO, fd: os.Handle, buf: []u8, user: rawptr, callback: On_Read) {…}
     

    Reads from the given handle, at the handle's internal offset, at most len(buf) bytes, increases the file offset, and calls the given callback

    Due to platform limitations, you must pass a `os.Handle` that was opened/returned using/by this package

    Inputs:
    io: The IO instance to use fd: The file handle (created using/by this package) to read from buf: The buffer to put read bytes into user: A pointer that will be passed through to the callback, free to use by you and untouched by us callback: The callback that is called when the operation completes, see docs for On_Read for its arguments

    read_all ¶

    read_all :: proc(io: ^_IO, fd: os.Handle, buf: []u8, user: rawptr, callback: On_Read) {…}
     

    Reads from the given handle, at the handle's internal offset, until the given buf is full or an error occurred, increases the file offset, and calls the given callback

    Due to platform limitations, you must pass a `os.Handle` that was opened/returned using/by this package

    Inputs:
    io: The IO instance to use fd: The file handle (created using/by this package) to read from buf: The buffer to put read bytes into user: A pointer that will be passed through to the callback, free to use by you and untouched by us callback: The callback that is called when the operation completes, see docs for On_Read for its arguments

    read_at ¶

    read_at :: proc(
    	io:       ^_IO, 
    	fd:       os.Handle, 
    	offset:   int, 
    	buf:      []u8, 
    	user:     rawptr, 
    	callback: On_Read, 
    ) {…}
     

    Reads from the given handle, at the given offset, at most len(buf) bytes, and calls the given callback

    Due to platform limitations, you must pass a `os.Handle` that was opened/returned using/by this package

    Inputs:
    io: The IO instance to use fd: The file handle (created using/by this package) to read from offset: The offset to begin the read from buf: The buffer to put read bytes into user: A pointer that will be passed through to the callback, free to use by you and untouched by us callback: The callback that is called when the operation completes, see docs for On_Read for its arguments

    read_at_all ¶

    read_at_all :: proc(
    	io:       ^_IO, 
    	fd:       os.Handle, 
    	offset:   int, 
    	buf:      []u8, 
    	user:     rawptr, 
    	callback: On_Read, 
    ) {…}
     

    Reads from the given handle, at the given offset, until the given buf is full or an error occurred, and calls the given callback

    Due to platform limitations, you must pass a `os.Handle` that was opened/returned using/by this package

    Inputs:
    io: The IO instance to use fd: The file handle (created using/by this package) to read from offset: The offset to begin the read from buf: The buffer to put read bytes into user: A pointer that will be passed through to the callback, free to use by you and untouched by us callback: The callback that is called when the operation completes, see docs for On_Read for its arguments

    read_entire_file ¶

    read_entire_file :: read_full
     

    Reads the entire file (size found by seeking to the end) into a singly allocated buffer that is returned. The callback is called once the file is read into the returned buf.

    Due to platform limitations, you must pass a `os.Handle` that was opened/returned using/by this package

    Inputs:
    io: The IO instance to use fd: The file handle (created using/by this package) to read from user: A pointer that will be passed through to the callback, free to use by you and untouched by us callback: The callback that is called when the operation completes, see docs for On_Read for its arguments

    Returns:
    buf: The buffer allocated to the size retrieved by seeking to the end of the file that is filled before calling the callback

    read_full ¶

    read_full :: proc(io: ^_IO, fd: os.Handle, user: rawptr, callback: On_Read, allocator := context.allocator) -> []u8 {…}
     

    Reads the entire file (size found by seeking to the end) into a singly allocated buffer that is returned. The callback is called once the file is read into the returned buf.

    Due to platform limitations, you must pass a `os.Handle` that was opened/returned using/by this package

    Inputs:
    io: The IO instance to use fd: The file handle (created using/by this package) to read from user: A pointer that will be passed through to the callback, free to use by you and untouched by us callback: The callback that is called when the operation completes, see docs for On_Read for its arguments

    Returns:
    buf: The buffer allocated to the size retrieved by seeking to the end of the file that is filled before calling the callback

    recv ¶

    recv :: proc(io: ^_IO, socket: net.Any_Socket, buf: []u8, user: rawptr, callback: On_Recv) {…}
     

    Receives from the given socket, at most len(buf) bytes, and calls the given callback

    Due to platform limitations, you must pass a `net.TCP_Socket` or `net.UDP_Socket` that was opened/returned using/by this package

    Inputs:
    io: The IO instance to use socket: Either a net.TCP_Socket or a net.UDP_Socket (that was opened/returned by this package) to receive from buf: The buffer to put received bytes into user: A pointer that will be passed through to the callback, free to use by you and untouched by us callback: The callback that is called when the operation completes, see docs for On_Recv for its arguments

    recv_all ¶

    recv_all :: proc(io: ^_IO, socket: net.Any_Socket, buf: []u8, user: rawptr, callback: On_Recv) {…}
     

    Receives from the given socket until the given buf is full or an error occurred, and calls the given callback

    Due to platform limitations, you must pass a `net.TCP_Socket` or `net.UDP_Socket` that was opened/returned using/by this package

    Inputs:
    io: The IO instance to use socket: Either a net.TCP_Socket or a net.UDP_Socket (that was opened/returned by this package) to receive from buf: The buffer to put received bytes into user: A pointer that will be passed through to the callback, free to use by you and untouched by us callback: The callback that is called when the operation completes, see docs for On_Recv for its arguments

    seek ¶

    seek :: proc(io: ^_IO, fd: os.Handle, offset: int, whence: Whence = .Set) -> (new_offset: int, err: os.Error) {…}
     

    Seeks the given handle according to the given offset and whence, so that subsequent read and writes USING THIS PACKAGE will do so at that offset

    Some platforms require this package to handle offsets while others have state in the kernel, for this reason you should assume that seeking only affects this package

    Inputs:
    io: The IO instance to seek on fd: The file handle to seek whence: The seek mode/where to seek from (default: Whence.Set)

    Returns:
    new_offset: The offset that the file is at when the operation completed err: The error when an error occured, 0 otherwise

    send_all_tcp ¶

    send_all_tcp :: proc(io: ^_IO, socket: net.TCP_Socket, buf: []u8, user: rawptr, callback: On_Sent) {…}
     

    Sends the bytes from the given buffer over the socket connection, and calls the given callback

    This will keep sending until either an error or the full buffer is sent

    Prefer using the `send` proc group

    Due to platform limitations, you must pass a `net.TCP_Socket` that was opened/returned using/by this package

    Inputs:
    io: The IO instance to use socket: a net.TCP_Socket (that was opened/returned by this package) to send to buf: The buffer send user: A pointer that will be passed through to the callback, free to use by you and untouched by us callback: The callback that is called when the operation completes, see docs for On_Sent for its arguments

    send_all_udp ¶

    send_all_udp :: proc(
    	io:       ^_IO, 
    	endpoint: net.Endpoint, 
    	socket:   net.UDP_Socket, 
    	buf:      []u8, 
    	user:     rawptr, 
    	callback: On_Sent, 
    ) {…}
     

    Sends the bytes from the given buffer over the socket connection to the given endpoint, and calls the given callback

    This will keep sending until either an error or the full buffer is sent

    Prefer using the `send` proc group

    Due to platform limitations, you must pass a `net.UDP_Socket` that was opened/returned using/by this package

    Inputs:
    io: The IO instance to use endpoint: The endpoint to send bytes to over the socket socket: a net.UDP_Socket (that was opened/returned by this package) to send to buf: The buffer send user: A pointer that will be passed through to the callback, free to use by you and untouched by us callback: The callback that is called when the operation completes, see docs for On_Sent for its arguments

    send_tcp ¶

    send_tcp :: proc(io: ^_IO, socket: net.TCP_Socket, buf: []u8, user: rawptr, callback: On_Sent) {…}
     

    Sends at most len(buf) bytes from the given buffer over the socket connection, and calls the given callback

    Prefer using the `send` proc group

    Due to platform limitations, you must pass a `net.TCP_Socket` that was opened/returned using/by this package

    Inputs:
    io: The IO instance to use socket: a net.TCP_Socket (that was opened/returned by this package) to send to buf: The buffer send user: A pointer that will be passed through to the callback, free to use by you and untouched by us callback: The callback that is called when the operation completes, see docs for On_Sent for its arguments

    send_udp ¶

    send_udp :: proc(
    	io:       ^_IO, 
    	endpoint: net.Endpoint, 
    	socket:   net.UDP_Socket, 
    	buf:      []u8, 
    	user:     rawptr, 
    	callback: On_Sent, 
    ) {…}
     

    Sends at most len(buf) bytes from the given buffer over the socket connection to the given endpoint, and calls the given callback

    Prefer using the `send` proc group

    Due to platform limitations, you must pass a `net.UDP_Socket` that was opened/returned using/by this package

    Inputs:
    io: The IO instance to use endpoint: The endpoint to send bytes to over the socket socket: a net.UDP_Socket (that was opened/returned by this package) to send to buf: The buffer send user: A pointer that will be passed through to the callback, free to use by you and untouched by us callback: The callback that is called when the operation completes, see docs for On_Sent for its arguments

    tick ¶

    tick :: proc(io: ^_IO) -> os.Error {…}
     

    The place where the magic happens, each time you call this the IO implementation checks its state and calls any callbacks which are ready. You would typically call this in a loop

    Inputs:
    io: The IO instance to tick

    Returns:
    err: An error code when something went when retrieving events, 0 otherwise

    timeout ¶

    timeout :: proc(io: ^_IO, dur: time.Duration, user: rawptr, callback: On_Timeout) {…}
     

    Schedules a callback to be called after the given duration elapses.

    The accuracy depends on the time between calls to tick. When you call it in a loop with no blocks or very expensive calculations in other scheduled event callbacks it is reliable to about a ms of difference (so timeout of 10ms would almost always be ran between 10ms and 11ms).

    Inputs:
    io: The IO instance to use dur: The minimum duration to wait before calling the given callback user: A pointer that will be passed through to the callback, free to use by you and untouched by us callback: The callback that is called when the operation completes, see docs for On_Timeout for its arguments

    write ¶

    write :: proc(io: ^_IO, fd: os.Handle, buf: []u8, user: rawptr, callback: On_Write) {…}
     

    Writes to the given handle, at the handle's internal offset, at most len(buf) bytes, increases the file offset, and calls the given callback

    Due to platform limitations, you must pass a `os.Handle` that was opened/returned using/by this package

    Inputs:
    io: The IO instance to use fd: The file handle (created using/by this package) to write to buf: The buffer to write to the file user: A pointer that will be passed through to the callback, free to use by you and untouched by us callback: The callback that is called when the operation completes, see docs for On_Write for its arguments

    write_all ¶

    write_all :: proc(io: ^_IO, fd: os.Handle, buf: []u8, user: rawptr, callback: On_Write) {…}
     

    Writes the given buffer to the given handle, at the handle's internal offset, increases the file offset, and calls the given callback

    This keeps writing until either an error or the full buffer being written

    Due to platform limitations, you must pass a `os.Handle` that was opened/returned using/by this package

    Inputs:
    io: The IO instance to use fd: The file handle (created using/by this package) to write to buf: The buffer to write to the file user: A pointer that will be passed through to the callback, free to use by you and untouched by us callback: The callback that is called when the operation completes, see docs for On_Write for its arguments

    write_at ¶

    write_at :: proc(
    	io:       ^_IO, 
    	fd:       os.Handle, 
    	offset:   int, 
    	buf:      []u8, 
    	user:     rawptr, 
    	callback: On_Write, 
    ) {…}
     

    Writes to the given handle, at the given offset, at most len(buf) bytes, and calls the given callback

    Due to platform limitations, you must pass a `os.Handle` that was opened/returned using/by this package

    Inputs:
    io: The IO instance to use fd: The file handle (created using/by this package) to write to from offset: The offset to begin the write from buf: The buffer to write to the file user: A pointer that will be passed through to the callback, free to use by you and untouched by us callback: The callback that is called when the operation completes, see docs for On_Write for its arguments

    write_at_all ¶

    write_at_all :: proc(
    	io:       ^_IO, 
    	fd:       os.Handle, 
    	offset:   int, 
    	buf:      []u8, 
    	user:     rawptr, 
    	callback: On_Write, 
    ) {…}
     

    Writes the given buffer to the given handle, at the given offset, and calls the given callback

    This keeps writing until either an error or the full buffer being written

    Due to platform limitations, you must pass a `os.Handle` that was opened/returned using/by this package

    Inputs:
    io: The IO instance to use fd: The file handle (created using/by this package) to write to from offset: The offset to begin the write from buf: The buffer to write to the file user: A pointer that will be passed through to the callback, free to use by you and untouched by us callback: The callback that is called when the operation completes, see docs for On_Write for its arguments

    Procedure Groups

    send ¶

    send :: proc{
    	send_udp,
    	send_tcp,
    }
    
     

    Sends at most len(buf) bytes from the given buffer over the socket connection, and calls the given callback

    Due to platform limitations, you must pass a `net.TCP_Socket` or `net.UDP_Socket` that was opened/returned using/by this package

    send_all ¶

    send_all :: proc{
    	send_all_udp,
    	send_all_tcp,
    }
    
     

    Sends the bytes from the given buffer over the socket connection, and calls the given callback

    This will keep sending until either an error or the full buffer is sent

    Due to platform limitations, you must pass a `net.TCP_Socket` or `net.UDP_Socket` that was opened/returned using/by this package

    Source Files

    Generation Information

    Generated with odin version dev-2024-10 (vendor "odin") Linux_amd64 @ 2024-10-30 12:34:52.774449235 +0000 UTC