libosmocore 1.10.0.65-d581
Osmocom core library
|
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_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. 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_msghdr * | iofd_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 msgb * | iofd_msgb_alloc (struct osmo_io_fd *iofd) |
convenience wrapper to call msgb_alloc with parameters from osmo_io_fd More... | |
struct msgb * | iofd_msgb_pending (struct osmo_io_fd *iofd) |
return the pending msgb in iofd or NULL if there is none More... | |
struct msgb * | iofd_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_msghdr * | iofd_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 |
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:
#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.
[in] | iofd | osmo_io_fd about which we're logging |
[in] | level | log-level (LOGL_DEBUG, LOGL_INFO, LOGL_NOTICE, LOGL_ERROR, LOGL_FATAL) |
[in] | fmt | printf-style format string |
[in] | args | arguments to the format string |
#define OSMO_IO_BACKEND_ENV "LIBOSMO_IO_BACKEND" |
This environment variable can be set to manually set the backend used in osmo_io.
enum 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.
enum 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 |
|
static |
References iofd_backend_ops::close, g_io_backend, iofd_poll_ops, iofd_backend_ops::notify_connected, OSMO_ASSERT, OSMO_IO_BACKEND_DEFAULT, OSMO_IO_BACKEND_ENV, OSMO_IO_BACKEND_IO_URING, OSMO_IO_BACKEND_POLL, osmo_iofd_init(), osmo_iofd_ops, iofd_backend_ops::read_disable, iofd_backend_ops::read_enable, iofd_backend_ops::register_fd, iofd_backend_ops::unregister_fd, iofd_backend_ops::write_disable, and iofd_backend_ops::write_enable.
|
static |
References mode, OSMO_IO_FD_MODE_READ_WRITE, OSMO_IO_FD_MODE_RECVFROM_SENDTO, OSMO_IO_FD_MODE_RECVMSG_SENDMSG, osmo_io_ops::read_cb, osmo_io_ops::recvfrom_cb, osmo_io_ops::recvmsg_cb, osmo_io_ops::segmentation_cb, osmo_io_ops::segmentation_cb2, osmo_io_ops::sendmsg_cb, osmo_io_ops::sendto_cb, and osmo_io_ops::write_cb.
Referenced by osmo_iofd_set_ioops(), and osmo_iofd_setup().
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
[in] | iofd | I/O file-descriptor on which I/O has completed |
[in] | msg | message buffer containing data related to completed I/O |
[in] | rc | result code with read size or error (-errno) |
[in] | hdr | serialized 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().
|
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().
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_FLAG_FD_REGISTERED, IOFD_FLAG_ISSET, iofd_handle_segmentation(), IOFD_SEG_ACT_DEFER, IOFD_SEG_ACT_HANDLE_MORE, osmo_io_fd::mode, msg, msgb_free(), OSMO_ASSERT, OSMO_IO_FD_MODE_READ_WRITE, osmo_io_fd::pending, osmo_io_ops::read_cb, and res.
Referenced by iofd_handle_recv().
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
[in] | iofd | I/O file-descriptor on which I/O has completed |
[in] | rc | return value of the I/O operation |
[in] | msghdr | serialized 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().
struct msgb * iofd_msgb_alloc | ( | struct osmo_io_fd * | iofd | ) |
convenience wrapper to call msgb_alloc with parameters from osmo_io_fd
References osmo_io_fd::headroom, osmo_io_fd::msgb_alloc, msgb_alloc_headroom_c(), OSMO_ASSERT, and osmo_io_fd::size.
Referenced by iofd_handle_segmentation(), iofd_msgb_pending_or_alloc(), and iofd_msghdr_alloc().
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().
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().
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.
[in] | iofd | the osmo_io file structure |
[in] | action | the action this msg(hdr) is for (read, write, ..) |
[in] | msg | the msg buffer to use. Will allocate a new one if NULL |
[in] | cmsg_size | size (in bytes) of iofd_msghdr.cmsg buffer. Can be 0 if cmsg is not used. |
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().
void iofd_msghdr_free | ( | struct iofd_msghdr * | msghdr | ) |
Free the msghdr.
[in] | msghdr | the 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().
struct iofd_msghdr * iofd_txqueue_dequeue | ( | struct osmo_io_fd * | iofd | ) |
Dequeue a message from the front.
[in] | iofd | the file descriptor |
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().
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.
[in] | iofd | the file descriptor |
[in] | msghdr | the message to enqueue |
References osmo_io_fd::current_length, IOFD_FLAG_CLOSED, IOFD_FLAG_ISSET, iofd_msghdr::list, llist_add_tail(), LOGL_ERROR, LOGPIO, 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().
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.
[in] | iofd | the file descriptor |
[in] | msghdr | the 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().
|
inlinestatic |
return the string name of an osmo_io_backend
References get_value_string(), and osmo_io_backend_names.
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()
[in] | iofd | the file descriptor |
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(), osmo_iofd_unregister(), osmo_io_fd::pending, iofd_backend_ops::read_disable, and iofd_backend_ops::write_disable.
Referenced by 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.
[in] | iofd | the file descriptor |
References iofd_msghdr::iofd, IOFD_FLAG_IN_CALLBACK, IOFD_FLAG_ISSET, IOFD_FLAG_SET, IOFD_FLAG_TO_FREE, and osmo_iofd_close().
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().
[in] | iofd | the file descriptor |
References osmo_io_fd::data, and iofd_msghdr::iofd.
int osmo_iofd_get_fd | ( | const struct osmo_io_fd * | iofd | ) |
Retrieve the underlying file descriptor from an osmo_io_fd.
[in] | iofd | the file descriptor |
References osmo_io_fd::fd, and iofd_msghdr::iofd.
void osmo_iofd_get_ioops | ( | struct osmo_io_fd * | iofd, |
struct osmo_io_ops * | ioops | ||
) |
Retrieve the osmo_io_ops for an iofd.
[in] | iofd | Target iofd file descriptor |
[in] | ioops | caller-allocated osmo_io_ops structure to be filled |
References osmo_io_fd::io_ops, and iofd_msghdr::iofd.
const char * osmo_iofd_get_name | ( | const struct osmo_io_fd * | iofd | ) |
Retrieve the human-readable name of the given osmo_io_fd.
[in] | iofd | the file descriptor |
References iofd_msghdr::iofd, and osmo_io_fd::name.
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().
[in] | iofd | the file descriptor |
References iofd_msghdr::iofd, and osmo_io_fd::priv_nr.
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__().
|
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().
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 with res=0 and msgb=NULL) 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.
The fact that the write call-back is called with msgb=NULL can be used to distinguish before this "connected" notification and a socket write failure.
If the server transmits data quick enough after accepting the connection, it may happen that a read call-back is triggered towards the user before this special write-callback, since both events may come together from the kernel. Hence under those scenarios where server starts the communication, it is important not to assume or require that the write-callback(res=0, msgb=NULL) will be the first one triggered.
[in] | iofd | the 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.
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.
[in] | iofd | the iofd file descriptor |
[in] | fd | the 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. |
References osmo_io_fd::current_length, ENOTSUP, osmo_io_fd::fd, osmo_io_fd::io_ops, IOFD_FLAG_CLOSED, IOFD_FLAG_FD_REGISTERED, IOFD_FLAG_ISSET, IOFD_FLAG_SET, 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.
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.
[in] | iofd | file descriptor to write to |
[in] | msg | message buffer to send; is used to fill msgh->iov[] |
[in] | sendmsg_flags | Flags to pass to the send call |
[in] | msgh | 'struct msghdr' for name/control/flags. iov must be empty! |
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.
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.
[in] | iofd | file descriptor to write to |
[in] | msg | message buffer to send |
[in] | sendto_flags | Flags to pass to the send call |
[in] | dest | destination address to send the message to |
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.
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.
[in] | iofd | the file descriptor |
[in] | size | the size of the msgb when receiving data |
[in] | headroom | the 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.
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.
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().
[in] | iofd | the file descriptor |
[in] | data | the data to set |
References data, osmo_io_fd::data, and iofd_msghdr::iofd.
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().
[in] | iofd | Target iofd file descriptor |
[in] | ioops | osmo_io_ops structure to be copied to the osmo_io_fd. |
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.
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().
[in] | iofd | the file descriptor |
[in] | name | the name to set on the file descriptor |
References iofd_msghdr::iofd, name, osmo_io_fd::name, and osmo_talloc_replace_string().
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.
[in] | iofd | the file descriptor |
[in] | priv_nr | the private number to set |
References iofd_msghdr::iofd, and osmo_io_fd::priv_nr.
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.
[in] | iofd | the file descriptor |
[in] | size | the maximum size of the transmit queue |
References iofd_msghdr::iofd, osmo_io_fd::max_length, and osmo_io_fd::tx_queue.
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:
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.
[in] | ctx | the parent context from which to allocate |
[in] | fd | the underlying system file descriptor. May be -1 if not known yet; must then be specified at subsequent osmo_iofd_register() time. |
[in] | name | the optional human-readable name of the iofd; may be NULL |
[in] | mode | the osmo_io_fd_mode of the iofd, whether it should use read()/write(), sendto()/recvfrom() semantics. |
[in] | ioops | structure 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] | data | opaque user data pointer accessible by the ioops callbacks |
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.
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
[in] | iofd | the file descriptor |
References iofd_msghdr::hdr, iofd_msghdr::iofd, iofd_msghdr_free(), iofd_txqueue_dequeue(), and msgb_free().
Referenced by osmo_iofd_close().
unsigned int osmo_iofd_txqueue_len | ( | struct osmo_io_fd * | iofd | ) |
Retrieve the number of messages pending in the transmit queue.
[in] | iofd | the file descriptor |
References osmo_io_fd::current_length, and osmo_io_fd::tx_queue.
Referenced by iofd_poll_ofd_cb_recvmsg_sendmsg().
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().
[in] | iofd | the file descriptor |
References IOFD_FLAG_FD_REGISTERED, IOFD_FLAG_ISSET, IOFD_FLAG_UNSET, osmo_iofd_ops, and iofd_backend_ops::unregister_fd.
Referenced by osmo_iofd_close().
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.
[in] | iofd | osmo_io_fd file descriptor to write data to |
[in] | msg | message buffer containing the data to write |
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.
|
static |
Referenced by __attribute__(), and osmo_iofd_init().
|
extern |
Referenced by osmo_io_backend_name().
const struct value_string osmo_io_backend_names[] |
Referenced by osmo_io_backend_name().
|
extern |
Referenced by osmo_iofd_mode_name().
const struct value_string osmo_iofd_mode_names[] |
Referenced by osmo_iofd_mode_name().
struct iofd_backend_ops osmo_iofd_ops |