libosmocore 1.9.0.196-9975
Osmocom core library
Osmocom I/O interface

osmo_io is the new (2023) interface for performing asynchronous I/O. More...

Files

file  osmo_io.h
 io(_uring) abstraction osmo fd compatibility
 
file  osmo_io.c
 

Data Structures

struct  osmo_io_ops
 I/O operations (call-back functions) related to an osmo_io_fd. More...
 

Macros

#define LOGPIO(iofd, level, fmt, args...)    LOGP(DLIO, level, "iofd(%s)" fmt, iofd->name, ## args)
 log macro used for logging information related to the osmo_io_fd. More...
 
#define OSMO_IO_BACKEND_ENV   "LIBOSMO_IO_BACKEND"
 This environment variable can be set to manually set the backend used in osmo_io. More...
 

Enumerations

enum  osmo_io_fd_mode {
  OSMO_IO_FD_MODE_READ_WRITE ,
  OSMO_IO_FD_MODE_RECVFROM_SENDTO ,
  OSMO_IO_FD_MODE_RECVMSG_SENDMSG
}
 The mode of an osmo_io_fd determines if read/write, recvfrom/sendmsg or recvmsg/sendmsg semantics are used. More...
 
enum  osmo_io_backend {
  OSMO_IO_BACKEND_POLL ,
  OSMO_IO_BACKEND_IO_URING
}
 The back-end used by osmo_io. More...
 

Functions

static const char * osmo_io_backend_name (enum osmo_io_backend val)
 return the string name of an osmo_io_backend More...
 
static const char * osmo_iofd_mode_name (enum osmo_io_fd_mode val)
 return the string name of an osmo_io_mode More...
 
void osmo_iofd_init (void)
 initialize osmo_io for the current thread More...
 
struct osmo_io_fdosmo_iofd_setup (const void *ctx, int fd, const char *name, enum osmo_io_fd_mode mode, const struct osmo_io_ops *ioops, void *data)
 Allocate and setup a new iofd. More...
 
int osmo_iofd_set_cmsg_size (struct osmo_io_fd *iofd, size_t cmsg_size)
 Set the size of the control message buffer allocated when submitting recvmsg. More...
 
int osmo_iofd_register (struct osmo_io_fd *iofd, int fd)
 Register the osmo_io_fd for active I/O. More...
 
int osmo_iofd_unregister (struct osmo_io_fd *iofd)
 Unregister the given osmo_io_fd from osmo_io. More...
 
unsigned int osmo_iofd_txqueue_len (struct osmo_io_fd *iofd)
 Retrieve the number of messages pending in the transmit queue. More...
 
void osmo_iofd_txqueue_clear (struct osmo_io_fd *iofd)
 Clear the transmit queue of the given osmo_io_fd. More...
 
int osmo_iofd_close (struct osmo_io_fd *iofd)
 Close the given osmo_io_fd. More...
 
void osmo_iofd_free (struct osmo_io_fd *iofd)
 Free the given osmo_io_fd. More...
 
void osmo_iofd_notify_connected (struct osmo_io_fd *iofd)
 Request notification of the user if/when a client socket is connected. More...
 
int osmo_iofd_write_msgb (struct osmo_io_fd *iofd, struct msgb *msg)
 Write a message to a file descriptor / connected socket. More...
 
int osmo_iofd_sendto_msgb (struct osmo_io_fd *iofd, struct msgb *msg, int sendto_flags, const struct osmo_sockaddr *dest)
 Send a message through an unconnected socket. More...
 
int osmo_iofd_sendmsg_msgb (struct osmo_io_fd *iofd, struct msgb *msg, int sendmsg_flags, const struct msghdr *msgh)
 osmo_io equivalent of the sendmsg(2) socket API call. More...
 
void osmo_iofd_set_alloc_info (struct osmo_io_fd *iofd, unsigned int size, unsigned int headroom)
 Set the size and headroom of the msgb allocated when receiving messages. More...
 
void osmo_iofd_set_txqueue_max_length (struct osmo_io_fd *iofd, unsigned int max_length)
 Set the maximum number of messages enqueued for sending. More...
 
void * osmo_iofd_get_data (const struct osmo_io_fd *iofd)
 Retrieve the associated user-data from an osmo_io_fd. More...
 
void osmo_iofd_set_data (struct osmo_io_fd *iofd, void *data)
 Set the associated user-data from an osmo_io_fd. More...
 
unsigned int osmo_iofd_get_priv_nr (const struct osmo_io_fd *iofd)
 Retrieve the private number from an osmo_io_fd. More...
 
void osmo_iofd_set_priv_nr (struct osmo_io_fd *iofd, unsigned int priv_nr)
 Set the private number of an osmo_io_fd. More...
 
int osmo_iofd_get_fd (const struct osmo_io_fd *iofd)
 Retrieve the underlying file descriptor from an osmo_io_fd. More...
 
const char * osmo_iofd_get_name (const struct osmo_io_fd *iofd)
 Retrieve the human-readable name of the given osmo_io_fd. More...
 
void osmo_iofd_set_name (struct osmo_io_fd *iofd, const char *name)
 Set the human-readable name of the file descriptor. More...
 
int osmo_iofd_set_ioops (struct osmo_io_fd *iofd, const struct osmo_io_ops *ioops)
 Set the osmo_io_ops calbacks for an osmo_io_fd. More...
 
void osmo_iofd_get_ioops (struct osmo_io_fd *iofd, struct osmo_io_ops *ioops)
 Retrieve the osmo_io_ops for an iofd. More...
 
static __attribute__ ((constructor(103)))
 
struct iofd_msghdriofd_msghdr_alloc (struct osmo_io_fd *iofd, enum iofd_msg_action action, struct msgb *msg, size_t cmsg_size)
 Allocate the msghdr. More...
 
void iofd_msghdr_free (struct iofd_msghdr *msghdr)
 Free the msghdr. More...
 
struct msgbiofd_msgb_alloc (struct osmo_io_fd *iofd)
 convenience wrapper to call msgb_alloc with parameters from osmo_io_fd More...
 
struct msgbiofd_msgb_pending (struct osmo_io_fd *iofd)
 return the pending msgb in iofd or NULL if there is none More...
 
struct msgbiofd_msgb_pending_or_alloc (struct osmo_io_fd *iofd)
 Return the pending msgb or allocate and return a new one. More...
 
int iofd_txqueue_enqueue (struct osmo_io_fd *iofd, struct iofd_msghdr *msghdr)
 Enqueue a message to be sent. More...
 
void iofd_txqueue_enqueue_front (struct osmo_io_fd *iofd, struct iofd_msghdr *msghdr)
 Enqueue a message at the front. More...
 
struct iofd_msghdriofd_txqueue_dequeue (struct osmo_io_fd *iofd)
 Dequeue a message from the front. More...
 
static enum iofd_seg_act iofd_handle_segmentation (struct osmo_io_fd *iofd, struct msgb *msg, struct msgb **pending_out)
 Handle segmentation of the msg. More...
 
void iofd_handle_segmented_read (struct osmo_io_fd *iofd, struct msgb *msg, int rc)
 Restore message boundaries on read() and pass individual messages to the read callback. More...
 
void iofd_handle_recv (struct osmo_io_fd *iofd, struct msgb *msg, int rc, struct iofd_msghdr *hdr)
 completion handler: Internal function called by osmo_io_backend after a given I/O operation has completed More...
 
void iofd_handle_send_completion (struct osmo_io_fd *iofd, int rc, struct iofd_msghdr *msghdr)
 completion handler: Internal function called by osmo_io_backend after a given I/O operation has completed More...
 
static int check_mode_callback_compat (enum osmo_io_fd_mode mode, const struct osmo_io_ops *ops)
 

Variables

const struct value_string osmo_io_backend_names []
 
const struct value_string osmo_iofd_mode_names []
 
const struct value_string osmo_io_backend_names []
 
const struct value_string osmo_iofd_mode_names []
 
static enum osmo_io_backend g_io_backend
 
struct iofd_backend_ops osmo_iofd_ops
 

Detailed Description

osmo_io is the new (2023) interface for performing asynchronous I/O.

osmo_io encapsulates asynchronous, non-blocking I/O to sockets or other file descriptors with a submission/completion model.

For writes, the API user submits write requests, and receives completion call-backs once the write completes.

For reads, the API user specifies the size (and headroom) for message buffers, and osmo_io internally allocates msgb's accordingly. Whenever data arrives at the socket/file descriptor, osmo_io reads the data into such a msgb and hands it to a read-completion call-back provided by the API user.

A given socket/file descriptor is represented by struct osmo_io_fd. osmo_io_fd are named, i.e. the API user can provide a meaningful name describing the purpose (such as protocol/interface or the name of the remote peer). This allows osmo_io to log any related [error] messages using this name as context.

When implementing some SOCK_STREAM / SOCK_SEQPACKET based client/server transports (such as those on top of TCP or SCTP), you are most likely better off using the osmo_stream_cli / osmo_stream_srv abstractions provided by libosmo-netif. They in turn can be used in an osmo_io mode, see the respective documentation.

If you use osmo_io_fd directly, the life-cycle usually will look as follows:

  1. open some socket and bind and/or connect it
  2. Allocate an osmo_io_fd using osmo_iofd_setup(), configuring the mode and specifying the call-backs
  3. Registering it with osmo_iofd_register(), which enables reading
  4. Handle inbound data via {read,recvfrom,recvmsg} call-backs; write to it using osmo_iofd_{write,sendto_sendmsg}_msg()
  5. Eventually un-register it using osmo_iofd_unregister(). Afterwards, you can re-cycle the iofd by calling osmo_iofd_register() with a new file-descriptor, or free it using osmo_iofd_free().

Macro Definition Documentation

◆ LOGPIO

#define LOGPIO (   iofd,
  level,
  fmt,
  args... 
)     LOGP(DLIO, level, "iofd(%s)" fmt, iofd->name, ## args)

log macro used for logging information related to the osmo_io_fd.

Parameters
[in]iofdosmo_io_fd about which we're logging
[in]levellog-level (LOGL_DEBUG, LOGL_INFO, LOGL_NOTICE, LOGL_ERROR, LOGL_FATAL)
[in]fmtprintf-style format string
[in]argsarguments to the format string

◆ OSMO_IO_BACKEND_ENV

#define OSMO_IO_BACKEND_ENV   "LIBOSMO_IO_BACKEND"

This environment variable can be set to manually set the backend used in osmo_io.

Enumeration Type Documentation

◆ osmo_io_backend

The back-end used by osmo_io.

There can be multiple different back-ends available on a given system; only one of it is used for all I/O performed via osmo_io in one given process.

Enumerator
OSMO_IO_BACKEND_POLL 

classic back-end using poll(2) and direct read/write/recvfrom/sendto/recvmsg/sendmsg syscalls

OSMO_IO_BACKEND_IO_URING 

back-end using io_uring to perform efficient I/O and reduce syscall overhead

◆ osmo_io_fd_mode

The mode of an osmo_io_fd determines if read/write, recvfrom/sendmsg or recvmsg/sendmsg semantics are used.

Enumerator
OSMO_IO_FD_MODE_READ_WRITE 

use read() / write() semantics with read_cb/write_cb in osmo_io_ops

OSMO_IO_FD_MODE_RECVFROM_SENDTO 

use recvfrom() / sendto() semantics with recvfrom_cb/sendto_cb in osmo_io_ops

OSMO_IO_FD_MODE_RECVMSG_SENDMSG 

emulate recvmsg() / sendmsg() semantics with recvmsg_cb/sendto_cb in osmo_io_ops

Function Documentation

◆ __attribute__()

◆ check_mode_callback_compat()

◆ iofd_handle_recv()

void iofd_handle_recv ( struct osmo_io_fd iofd,
struct msgb msg,
int  rc,
struct iofd_msghdr hdr 
)

completion handler: Internal function called by osmo_io_backend after a given I/O operation has completed

Parameters
[in]iofdI/O file-descriptor on which I/O has completed
[in]msgmessage buffer containing data related to completed I/O
[in]rcresult code with read size or error (-errno)
[in]hdrserialized msghdr containing state of completed I/O

References osmo_io_fd::ctx, hdr, osmo_io_fd::io_ops, iofd_handle_segmented_read(), osmo_io_fd::mode, msg, osmo_io_fd::msgb_alloc, OSMO_ASSERT, OSMO_IO_FD_MODE_READ_WRITE, OSMO_IO_FD_MODE_RECVFROM_SENDTO, OSMO_IO_FD_MODE_RECVMSG_SENDMSG, osmo_io_ops::recvfrom_cb, and osmo_io_ops::recvmsg_cb.

Referenced by iofd_poll_ofd_cb_recvmsg_sendmsg().

◆ iofd_handle_segmentation()

static enum iofd_seg_act iofd_handle_segmentation ( struct osmo_io_fd iofd,
struct msgb msg,
struct msgb **  pending_out 
)
static

Handle segmentation of the msg.

If this function returns *_HANDLE_ONE or MORE then the data in msg will contain one complete message. If there are bytes left over, *pending_out will point to a msgb with the remaining data.

References data, osmo_io_fd::io_ops, iofd_msgb_alloc(), IOFD_SEG_ACT_DEFER, IOFD_SEG_ACT_HANDLE_MORE, IOFD_SEG_ACT_HANDLE_ONE, LOGL_ERROR, LOGPIO, msg, msgb_data(), msgb_free(), msgb_length(), msgb_put(), osmo_io_ops::segmentation_cb, and osmo_io_ops::segmentation_cb2.

Referenced by iofd_handle_segmented_read().

◆ iofd_handle_segmented_read()

void iofd_handle_segmented_read ( struct osmo_io_fd iofd,
struct msgb msg,
int  rc 
)

Restore message boundaries on read() and pass individual messages to the read callback.

References osmo_io_fd::io_ops, iofd_handle_segmentation(), IOFD_SEG_ACT_DEFER, IOFD_SEG_ACT_HANDLE_MORE, osmo_io_fd::mode, msg, OSMO_ASSERT, OSMO_IO_FD_MODE_READ_WRITE, osmo_io_fd::pending, osmo_io_ops::read_cb, and res.

Referenced by iofd_handle_recv().

◆ iofd_handle_send_completion()

void iofd_handle_send_completion ( struct osmo_io_fd iofd,
int  rc,
struct iofd_msghdr msghdr 
)

completion handler: Internal function called by osmo_io_backend after a given I/O operation has completed

Parameters
[in]iofdI/O file-descriptor on which I/O has completed
[in]rcreturn value of the I/O operation
[in]msghdrserialized msghdr containing state of completed I/O

References iofd_msghdr::action, osmo_io_fd::io_ops, IOFD_ACT_SENDMSG, IOFD_ACT_SENDTO, IOFD_ACT_WRITE, iofd_msghdr_free(), iofd_txqueue_enqueue_front(), iofd_msghdr::iov, msg, iofd_msghdr::msg, msgb_free(), msgb_length(), msgb_pull(), iofd_msghdr::osa, OSMO_ASSERT, osmo_io_ops::sendmsg_cb, osmo_io_ops::sendto_cb, and osmo_io_ops::write_cb.

Referenced by iofd_poll_ofd_cb_recvmsg_sendmsg().

◆ iofd_msgb_alloc()

struct msgb * iofd_msgb_alloc ( struct osmo_io_fd iofd)

◆ iofd_msgb_pending()

struct msgb * iofd_msgb_pending ( struct osmo_io_fd iofd)

return the pending msgb in iofd or NULL if there is none

References msg, and osmo_io_fd::pending.

Referenced by iofd_msgb_pending_or_alloc().

◆ iofd_msgb_pending_or_alloc()

struct msgb * iofd_msgb_pending_or_alloc ( struct osmo_io_fd iofd)

Return the pending msgb or allocate and return a new one.

References iofd_msgb_alloc(), iofd_msgb_pending(), and msg.

Referenced by iofd_poll_ofd_cb_recvmsg_sendmsg().

◆ iofd_msghdr_alloc()

struct iofd_msghdr * iofd_msghdr_alloc ( struct osmo_io_fd iofd,
enum iofd_msg_action  action,
struct msgb msg,
size_t  cmsg_size 
)

Allocate the msghdr.

Parameters
[in]iofdthe osmo_io file structure
[in]actionthe action this msg(hdr) is for (read, write, ..)
[in]msgthe msg buffer to use. Will allocate a new one if NULL
[in]cmsg_sizesize (in bytes) of iofd_msghdr.cmsg buffer. Can be 0 if cmsg is not used.
Returns
the newly allocated msghdr or NULL in case of error

References iofd_msghdr::action, iofd_msghdr::hdr, iofd_msghdr::iofd, iofd_msgb_alloc(), and iofd_msghdr::msg.

Referenced by osmo_iofd_sendmsg_msgb(), osmo_iofd_sendto_msgb(), and osmo_iofd_write_msgb().

◆ iofd_msghdr_free()

void iofd_msghdr_free ( struct iofd_msghdr msghdr)

Free the msghdr.

Parameters
[in]msghdrthe msghdr to free

Referenced by iofd_handle_send_completion(), osmo_iofd_sendmsg_msgb(), osmo_iofd_sendto_msgb(), osmo_iofd_txqueue_clear(), and osmo_iofd_write_msgb().

◆ iofd_txqueue_dequeue()

struct iofd_msghdr * iofd_txqueue_dequeue ( struct osmo_io_fd iofd)

Dequeue a message from the front.

Parameters
[in]iofdthe file descriptor
Returns
the msghdr from the front of the queue or NULL if the queue is empty

References osmo_io_fd::current_length, list, llist_del(), llist_entry, osmo_io_fd::msg_queue, llist_head::next, OSMO_ASSERT, osmo_iofd_ops, osmo_io_fd::tx_queue, and iofd_backend_ops::write_disable.

Referenced by iofd_poll_ofd_cb_recvmsg_sendmsg(), and osmo_iofd_txqueue_clear().

◆ iofd_txqueue_enqueue()

int iofd_txqueue_enqueue ( struct osmo_io_fd iofd,
struct iofd_msghdr msghdr 
)

Enqueue a message to be sent.

Enqueues the message at the back of the queue provided there is enough space.

Parameters
[in]iofdthe file descriptor
[in]msghdrthe message to enqueue
Returns
0 if the message was enqueued succcessfully, -ENOSPC if the queue already contains the maximum number of messages

References osmo_io_fd::current_length, IOFD_FLAG_CLOSED, IOFD_FLAG_ISSET, iofd_msghdr::list, llist_add_tail(), osmo_io_fd::max_length, osmo_io_fd::msg_queue, osmo_iofd_ops, osmo_io_fd::tx_queue, and iofd_backend_ops::write_enable.

Referenced by osmo_iofd_sendmsg_msgb(), osmo_iofd_sendto_msgb(), and osmo_iofd_write_msgb().

◆ iofd_txqueue_enqueue_front()

void iofd_txqueue_enqueue_front ( struct osmo_io_fd iofd,
struct iofd_msghdr msghdr 
)

Enqueue a message at the front.

Used to enqueue a msgb from a partial send again. This function will always enqueue the message, even if the maximum number of messages is reached.

Parameters
[in]iofdthe file descriptor
[in]msghdrthe message to enqueue

References osmo_io_fd::current_length, IOFD_FLAG_CLOSED, IOFD_FLAG_ISSET, iofd_msghdr::list, llist_add(), osmo_io_fd::msg_queue, osmo_iofd_ops, osmo_io_fd::tx_queue, and iofd_backend_ops::write_enable.

Referenced by iofd_handle_send_completion().

◆ osmo_io_backend_name()

static const char * osmo_io_backend_name ( enum osmo_io_backend  val)
inlinestatic

return the string name of an osmo_io_backend

References get_value_string(), and osmo_io_backend_names.

◆ osmo_iofd_close()

int osmo_iofd_close ( struct osmo_io_fd iofd)

Close the given osmo_io_fd.

This function closes the underlying fd, unregisters it from osmo_io and clears any messages in the tx queue. The iofd itself is not freed and can be assigned a new file descriptor with osmo_iofd_register()

Parameters
[in]iofdthe file descriptor
Returns
0 on success, a negative value otherwise

References iofd_backend_ops::close, osmo_io_fd::fd, iofd_msghdr::iofd, IOFD_FLAG_CLOSED, IOFD_FLAG_ISSET, IOFD_FLAG_SET, msgb_free(), osmo_iofd_ops, osmo_iofd_txqueue_clear(), and osmo_io_fd::pending.

Referenced by osmo_iofd_free().

◆ osmo_iofd_free()

void osmo_iofd_free ( struct osmo_io_fd iofd)

Free the given osmo_io_fd.

The iofd will be automatically closed before via osmo_iofd_close() [which in turn will unregister it and clear any pending transmit queue items]. You must not reference the iofd after calling this function. However, it is safe to call this function from any of osmo_io call-backs; in this case, actual free will be internally delayed until that call-back completes.

Parameters
[in]iofdthe file descriptor

References iofd_msghdr::iofd, IOFD_FLAG_IN_CALLBACK, IOFD_FLAG_ISSET, IOFD_FLAG_SET, IOFD_FLAG_TO_FREE, and osmo_iofd_close().

◆ osmo_iofd_get_data()

void * osmo_iofd_get_data ( const struct osmo_io_fd iofd)

Retrieve the associated user-data from an osmo_io_fd.

A call to this function will return the opaque user data pointer which was specified previously via osmo_iofd_setup() or via osmo_iofd_set_data().

Parameters
[in]iofdthe file descriptor
Returns
the data that was previously set with osmo_iofd_setup()

References osmo_io_fd::data, and iofd_msghdr::iofd.

◆ osmo_iofd_get_fd()

int osmo_iofd_get_fd ( const struct osmo_io_fd iofd)

Retrieve the underlying file descriptor from an osmo_io_fd.

Parameters
[in]iofdthe file descriptor
Returns
the underlying file descriptor number

References osmo_io_fd::fd, and iofd_msghdr::iofd.

◆ osmo_iofd_get_ioops()

void osmo_iofd_get_ioops ( struct osmo_io_fd iofd,
struct osmo_io_ops ioops 
)

Retrieve the osmo_io_ops for an iofd.

Parameters
[in]iofdTarget iofd file descriptor
[in]ioopscaller-allocated osmo_io_ops structure to be filled

References osmo_io_fd::io_ops, and iofd_msghdr::iofd.

◆ osmo_iofd_get_name()

const char * osmo_iofd_get_name ( const struct osmo_io_fd iofd)

Retrieve the human-readable name of the given osmo_io_fd.

Parameters
[in]iofdthe file descriptor
Returns
the name of the iofd as given in osmo_iofd_setup()

References iofd_msghdr::iofd, and osmo_io_fd::name.

◆ osmo_iofd_get_priv_nr()

unsigned int osmo_iofd_get_priv_nr ( const struct osmo_io_fd iofd)

Retrieve the private number from an osmo_io_fd.

Calling this function will retrieve the private user number previously set via osmo_iofd_set_priv_nr().

Parameters
[in]iofdthe file descriptor
Returns
the private number that was previously set with osmo_iofd_set_priv_nr()

References iofd_msghdr::iofd, and osmo_io_fd::priv_nr.

◆ osmo_iofd_init()

void osmo_iofd_init ( void  )

initialize osmo_io for the current thread

References g_io_backend, OSMO_ASSERT, OSMO_IO_BACKEND_IO_URING, and OSMO_IO_BACKEND_POLL.

Referenced by __attribute__().

◆ osmo_iofd_mode_name()

static const char * osmo_iofd_mode_name ( enum osmo_io_fd_mode  val)
inlinestatic

return the string name of an osmo_io_mode

References get_value_string(), and osmo_iofd_mode_names.

Referenced by osmo_iofd_set_ioops(), and osmo_iofd_setup().

◆ osmo_iofd_notify_connected()

void osmo_iofd_notify_connected ( struct osmo_io_fd iofd)

Request notification of the user if/when a client socket is connected.

Calling this function will request osmo_io to notify the user (via write call-back) once a non-blocking outbound connect() of the socket completes.

This only works for connection oriented sockets in either OSMO_IO_FD_MODE_READ_WRITE or OSMO_IO_FD_MODE_RECVMSG_SENDMSG mode.

Parameters
[in]iofdthe file descriptor

References iofd_msghdr::iofd, osmo_io_fd::mode, iofd_backend_ops::notify_connected, OSMO_ASSERT, OSMO_IO_FD_MODE_READ_WRITE, OSMO_IO_FD_MODE_RECVMSG_SENDMSG, and osmo_iofd_ops.

◆ osmo_iofd_register()

int osmo_iofd_register ( struct osmo_io_fd iofd,
int  fd 
)

Register the osmo_io_fd for active I/O.

Calling this function will register a previously initialized osmo_io_fd for performing I/O.

If the osmo_iofd has a read_cb/recvfrom_cb_recvmsg_cb set in its osmo_io_ops, read/receive will be automatically enabled and the respective call-back is called at any time data becomes available.

If there is to-be-transmitted data in the transmit queue, write will be automatically enabled, allowing the transmit queue to be drained as soon as the fd/socket becomes writable.

Parameters
[in]iofdthe iofd file descriptor
[in]fdthe system fd number that will be registered. If you did not yet specify the file descriptor number during osmo_fd_setup(), or if it has changed since then, you can state the [new] file descriptor number as argument. If you wish to proceed with the previously specified file descriptor number, pass -1.
Returns
zero on success, a negative value on error

References osmo_io_fd::current_length, osmo_io_fd::fd, osmo_io_fd::io_ops, IOFD_FLAG_CLOSED, IOFD_FLAG_UNSET, LOGL_ERROR, LOGPIO, osmo_io_fd::mode, OSMO_IO_FD_MODE_READ_WRITE, OSMO_IO_FD_MODE_RECVFROM_SENDTO, OSMO_IO_FD_MODE_RECVMSG_SENDMSG, osmo_iofd_ops, osmo_io_ops::read_cb, iofd_backend_ops::read_enable, osmo_io_ops::recvfrom_cb, osmo_io_ops::recvmsg_cb, iofd_backend_ops::register_fd, osmo_io_fd::tx_queue, and iofd_backend_ops::write_enable.

◆ osmo_iofd_sendmsg_msgb()

int osmo_iofd_sendmsg_msgb ( struct osmo_io_fd iofd,
struct msgb msg,
int  sendmsg_flags,
const struct msghdr *  msgh 
)

osmo_io equivalent of the sendmsg(2) socket API call.

The osmo_io_fd must be using OSMO_IO_FD_MODE_RECVMSG_SENDMSG.

Appends the message to the internal transmit queue for eventual non-blocking sendmsg on the underlying socket/file descriptor.

If the function returns success (0), it will take ownership of the msgb and internally call msgb_free() after the sendmsg request completes. In case of an error the msgb needs to be freed by the caller.

Parameters
[in]iofdfile descriptor to write to
[in]msgmessage buffer to send; is used to fill msgh->iov[]
[in]sendmsg_flagsFlags to pass to the send call
[in]msgh'struct msghdr' for name/control/flags. iov must be empty!
Returns
0 in case of success; a negative value in case of error

References iofd_msghdr::cmsg, iofd_msghdr::hdr, iofd_msghdr::iofd, IOFD_ACT_SENDMSG, iofd_msghdr_alloc(), iofd_msghdr_free(), iofd_txqueue_enqueue(), iofd_msghdr::iov, LOGL_ERROR, LOGPIO, osmo_io_fd::mode, iofd_msghdr::msg, msgb_data(), msgb_length(), iofd_msghdr::osa, OSMO_ASSERT, OSMO_IO_FD_MODE_RECVMSG_SENDMSG, OSMO_UNLIKELY, osmo_sockaddr::sa, and osmo_sockaddr::u.

◆ osmo_iofd_sendto_msgb()

int osmo_iofd_sendto_msgb ( struct osmo_io_fd iofd,
struct msgb msg,
int  sendto_flags,
const struct osmo_sockaddr dest 
)

Send a message through an unconnected socket.

The osmo_io_fd must be using OSMO_IO_FD_MODE_RECVFROM_SENDTO.

Appends the message to the internal transmit queue for eventual non-blocking sendto on the underlying socket/file descriptor.

If the function returns success (0), it will take ownership of the msgb and internally call msgb_free() after the sendto request completes. In case of an error the msgb needs to be freed by the caller.

Parameters
[in]iofdfile descriptor to write to
[in]msgmessage buffer to send
[in]sendto_flagsFlags to pass to the send call
[in]destdestination address to send the message to
Returns
0 in case of success; a negative value in case of error

References iofd_msghdr::flags, iofd_msghdr::hdr, iofd_msghdr::iofd, IOFD_ACT_SENDTO, iofd_msghdr_alloc(), iofd_msghdr_free(), iofd_txqueue_enqueue(), iofd_msghdr::iov, LOGL_ERROR, LOGPIO, osmo_io_fd::mode, iofd_msghdr::msg, msgb_data(), msgb_length(), iofd_msghdr::osa, OSMO_ASSERT, OSMO_IO_FD_MODE_RECVFROM_SENDTO, osmo_sockaddr_size(), OSMO_UNLIKELY, osmo_sockaddr::sa, and osmo_sockaddr::u.

◆ osmo_iofd_set_alloc_info()

void osmo_iofd_set_alloc_info ( struct osmo_io_fd iofd,
unsigned int  size,
unsigned int  headroom 
)

Set the size and headroom of the msgb allocated when receiving messages.

Parameters
[in]iofdthe file descriptor
[in]sizethe size of the msgb when receiving data
[in]headroomthe headroom of the msgb when receiving data

References osmo_io_fd::headroom, iofd_msghdr::iofd, osmo_io_fd::msgb_alloc, and osmo_io_fd::size.

◆ osmo_iofd_set_cmsg_size()

int osmo_iofd_set_cmsg_size ( struct osmo_io_fd iofd,
size_t  cmsg_size 
)

Set the size of the control message buffer allocated when submitting recvmsg.

If your osmo_io_fd is in OSMO_IO_FD_MODE_RECVMSG_SENDMSG mode, this API function can be used to tell the osmo_io code how much memory should be allocated for the cmsg (control message) buffer when performing recvmsg().

References osmo_io_fd::cmsg_size, osmo_io_fd::mode, and OSMO_IO_FD_MODE_RECVMSG_SENDMSG.

◆ osmo_iofd_set_data()

void osmo_iofd_set_data ( struct osmo_io_fd iofd,
void *  data 
)

Set the associated user-data from an osmo_io_fd.

Calling this function will set/overwrite the opaque user data pointer, which can later be retrieved using osmo_iofd_get_data().

Parameters
[in]iofdthe file descriptor
[in]datathe data to set

References data, osmo_io_fd::data, and iofd_msghdr::iofd.

◆ osmo_iofd_set_ioops()

int osmo_iofd_set_ioops ( struct osmo_io_fd iofd,
const struct osmo_io_ops ioops 
)

Set the osmo_io_ops calbacks for an osmo_io_fd.

This function can be used to update/overwrite the call-back functions for the given osmo_io_fd; it replaces the currently-set call-back function pointers from a previous call to osmo_iofd_set_ioops() or the original osmo_iofd_setup().

Parameters
[in]iofdTarget iofd file descriptor
[in]ioopsosmo_io_ops structure to be copied to the osmo_io_fd.
Returns
0 on success, negative on error

References check_mode_callback_compat(), osmo_io_fd::io_ops, iofd_msghdr::iofd, LOGL_ERROR, LOGPIO, osmo_io_fd::mode, OSMO_ASSERT, OSMO_IO_FD_MODE_READ_WRITE, OSMO_IO_FD_MODE_RECVFROM_SENDTO, OSMO_IO_FD_MODE_RECVMSG_SENDMSG, osmo_iofd_mode_name(), osmo_iofd_ops, osmo_io_ops::read_cb, iofd_backend_ops::read_disable, iofd_backend_ops::read_enable, osmo_io_ops::recvfrom_cb, and osmo_io_ops::recvmsg_cb.

◆ osmo_iofd_set_name()

void osmo_iofd_set_name ( struct osmo_io_fd iofd,
const char *  name 
)

Set the human-readable name of the file descriptor.

The given name will be used as context by all related logging and future calls to osmo_iofd_get_name().

Parameters
[in]iofdthe file descriptor
[in]namethe name to set on the file descriptor

References iofd_msghdr::iofd, name, osmo_io_fd::name, and osmo_talloc_replace_string().

◆ osmo_iofd_set_priv_nr()

void osmo_iofd_set_priv_nr ( struct osmo_io_fd iofd,
unsigned int  priv_nr 
)

Set the private number of an osmo_io_fd.

The priv_nr passed in via this call can later be retrieved via osmo_iofd_get_priv_nr(). It provides a way how additional context can be stored in the osmo_io_fd beyond the opaque 'data' pointer.

Parameters
[in]iofdthe file descriptor
[in]priv_nrthe private number to set

References iofd_msghdr::iofd, and osmo_io_fd::priv_nr.

◆ osmo_iofd_set_txqueue_max_length()

void osmo_iofd_set_txqueue_max_length ( struct osmo_io_fd iofd,
unsigned int  max_length 
)

Set the maximum number of messages enqueued for sending.

Parameters
[in]iofdthe file descriptor
[in]sizethe maximum size of the transmit queue

References iofd_msghdr::iofd, osmo_io_fd::max_length, and osmo_io_fd::tx_queue.

◆ osmo_iofd_setup()

struct osmo_io_fd * osmo_iofd_setup ( const void *  ctx,
int  fd,
const char *  name,
enum osmo_io_fd_mode  mode,
const struct osmo_io_ops ioops,
void *  data 
)

Allocate and setup a new iofd.

Use this to create a new osmo_io_fd, specifying the osmo_io_fd_mode and osmo_io_ops, as well as optionally the file-descriptor number and a human-readable name. This is the first function you call for any osmo_io_fd.

The created osmo_io_fd is not yet registered, and hence can not be used for any I/O until a subsequent call to osmo_iofd_register().

The created osmo_io_fd is initialized with some default settings:

  • msgb allocations size: OSMO_IO_DEFAULT_MSGB_SIZE (1024)
  • msgb headroom: OSMO_IO_DEFAULT_MSGB_HEADROOM (128)
  • tx_queue depth: 32

Those values may be adjusted from their defaults by using osmo_iofd_set_alloc_info() and osmo_iofd_set_txqueue_max_length() on the osmo_io_fd.

Parameters
[in]ctxthe parent context from which to allocate
[in]fdthe underlying system file descriptor. May be -1 if not known yet; must then be specified at subsequent osmo_iofd_register() time.
[in]namethe optional human-readable name of the iofd; may be NULL
[in]modethe osmo_io_fd_mode of the iofd, whether it should use read()/write(), sendto()/recvfrom() semantics.
[in]ioopsstructure specifying the read/write/send/recv callbacks. Will be copied to the iofd, so the caller does not have to keep it around after issuing the osmo_iofd_setup call.
[in]dataopaque user data pointer accessible by the ioops callbacks
Returns
The newly allocated osmo_io_fd struct or NULL on failure

References check_mode_callback_compat(), osmo_io_fd::ctx, data, osmo_io_fd::data, DLIO, osmo_io_fd::fd, osmo_io_fd::headroom, INIT_LLIST_HEAD, osmo_io_fd::io_ops, IOFD_FLAG_CLOSED, IOFD_FLAG_SET, LOGL_ERROR, LOGP, osmo_io_fd::max_length, osmo_io_fd::mode, osmo_io_fd::msg_queue, osmo_io_fd::msgb_alloc, name, osmo_io_fd::name, OSMO_IO_DEFAULT_MSGB_HEADROOM, OSMO_IO_DEFAULT_MSGB_SIZE, OSMO_IO_FD_MODE_READ_WRITE, OSMO_IO_FD_MODE_RECVFROM_SENDTO, OSMO_IO_FD_MODE_RECVMSG_SENDMSG, osmo_iofd_mode_name(), osmo_io_fd::pending, osmo_io_fd::size, and osmo_io_fd::tx_queue.

◆ osmo_iofd_txqueue_clear()

void osmo_iofd_txqueue_clear ( struct osmo_io_fd iofd)

Clear the transmit queue of the given osmo_io_fd.

This function frees all messages currently pending in the transmit queue

Parameters
[in]iofdthe file descriptor

References iofd_msghdr::hdr, iofd_msghdr::iofd, iofd_msghdr_free(), iofd_txqueue_dequeue(), and msgb_free().

Referenced by osmo_iofd_close().

◆ osmo_iofd_txqueue_len()

unsigned int osmo_iofd_txqueue_len ( struct osmo_io_fd iofd)

Retrieve the number of messages pending in the transmit queue.

Parameters
[in]iofdthe file descriptor

References osmo_io_fd::current_length, and osmo_io_fd::tx_queue.

Referenced by iofd_poll_ofd_cb_recvmsg_sendmsg().

◆ osmo_iofd_unregister()

int osmo_iofd_unregister ( struct osmo_io_fd iofd)

Unregister the given osmo_io_fd from osmo_io.

After an osmo_io_fd has been successfully unregistered, it can no longer perform any I/O via osmo_io. However, it can be subsequently re-registered using osmo_iofd_register().

Parameters
[in]iofdthe file descriptor
Returns
zero on success, a negative value on error

References osmo_iofd_ops, and iofd_backend_ops::unregister_fd.

◆ osmo_iofd_write_msgb()

int osmo_iofd_write_msgb ( struct osmo_io_fd iofd,
struct msgb msg 
)

Write a message to a file descriptor / connected socket.

The osmo_io_fd must be using OSMO_IO_FD_MODE_READ_WRITE.

Appends the message to the internal transmit queue for eventual non-blocking write to the underlying socket/file descriptor.

If the function returns success (0) it will take ownership of the msgb and internally call msgb_free() after the write request completes. In case of an error, the msgb needs to be freed by the caller.

Parameters
[in]iofdosmo_io_fd file descriptor to write data to
[in]msgmessage buffer containing the data to write
Returns
0 in case of success; a negative value in case of error

References iofd_msghdr::flags, iofd_msghdr::hdr, iofd_msghdr::iofd, IOFD_ACT_WRITE, iofd_msghdr_alloc(), iofd_msghdr_free(), iofd_txqueue_enqueue(), iofd_msghdr::iov, LOGL_ERROR, LOGPIO, osmo_io_fd::mode, msg, iofd_msghdr::msg, msgb_data(), msgb_length(), OSMO_ASSERT, OSMO_IO_FD_MODE_READ_WRITE, and OSMO_UNLIKELY.

Variable Documentation

◆ g_io_backend

enum osmo_io_backend g_io_backend
static

Referenced by __attribute__(), and osmo_iofd_init().

◆ osmo_io_backend_names [1/2]

const struct value_string osmo_io_backend_names[]
extern

Referenced by osmo_io_backend_name().

◆ osmo_io_backend_names [2/2]

const struct value_string osmo_io_backend_names[]
Initial value:
= {
{ OSMO_IO_BACKEND_POLL, "poll" },
{ OSMO_IO_BACKEND_IO_URING, "io_uring" },
{ 0, NULL }
}
@ OSMO_IO_BACKEND_POLL
classic back-end using poll(2) and direct read/write/recvfrom/sendto/recvmsg/sendmsg syscalls
Definition: osmo_io.h:77
@ OSMO_IO_BACKEND_IO_URING
back-end using io_uring to perform efficient I/O and reduce syscall overhead
Definition: osmo_io.h:79

Referenced by osmo_io_backend_name().

◆ osmo_iofd_mode_names [1/2]

const struct value_string osmo_iofd_mode_names[]
extern

Referenced by osmo_iofd_mode_name().

◆ osmo_iofd_mode_names [2/2]

const struct value_string osmo_iofd_mode_names[]
Initial value:
= {
{ OSMO_IO_FD_MODE_READ_WRITE, "read/write" },
{ OSMO_IO_FD_MODE_RECVFROM_SENDTO, "recvfrom/sendto" },
{ OSMO_IO_FD_MODE_RECVMSG_SENDMSG, "recvmsg/sendmsg" },
{ 0, NULL }
}
@ OSMO_IO_FD_MODE_RECVFROM_SENDTO
use recvfrom() / sendto() semantics with recvfrom_cb/sendto_cb in osmo_io_ops
Definition: osmo_io.h:68
@ OSMO_IO_FD_MODE_RECVMSG_SENDMSG
emulate recvmsg() / sendmsg() semantics with recvmsg_cb/sendto_cb in osmo_io_ops
Definition: osmo_io.h:70
@ OSMO_IO_FD_MODE_READ_WRITE
use read() / write() semantics with read_cb/write_cb in osmo_io_ops
Definition: osmo_io.h:66

Referenced by osmo_iofd_mode_name().

◆ osmo_iofd_ops