// Copyright 2020-2023, Collabora, Ltd. // SPDX-License-Identifier: BSL-1.0 /*! * @file * @brief IPC message channel functions. * @author Rylie Pavlik * @ingroup ipc_shared */ #pragma once #include #include #include #include #include #include "util/u_logging.h" #ifdef __cplusplus extern "C" { #endif /*! * Wrapper for a socket and flags. */ struct ipc_message_channel { xrt_ipc_handle_t ipc_handle; enum u_logging_level log_level; }; /*! * Close an IPC message channel * * @public @memberof ipc_message_channel */ void ipc_message_channel_close(struct ipc_message_channel *imc); /*! * Send a bare message over the IPC channel. * * There are other functions if you have handles, not just scalar/aggregate * data. * * @param imc Message channel to use * @param[in] data Pointer to the data buffer to send. Must not be * null: use a filler message if necessary. * @param[in] size Size of data pointed-to by @p data, must be greater than 0 * * @public @memberof ipc_message_channel */ xrt_result_t ipc_send(struct ipc_message_channel *imc, const void *data, size_t size); /*! * Receive a bare message over the IPC channel. * * There are other functions if you have handles, not just scalar/aggregate * data. * * @param imc Message channel to use * @param[out] out_data Pointer to the buffer to fill with data. Must not be * null. * @param[in] size Maximum size to read, must be greater than 0 * * @public @memberof ipc_message_channel */ xrt_result_t ipc_receive(struct ipc_message_channel *imc, void *out_data, size_t size); /*! * @name File Descriptor or HANDLE utilities * @brief These are typically called from within the send/receive_handles * functions. * @{ */ #ifdef XRT_OS_UNIX /*! * Receive a message along with a known number of file descriptors over the IPC * channel. * * @param imc Message channel to use * @param[out] out_data Pointer to the buffer to fill with data. Must not be * null. * @param[in] size Maximum size to read, must be greater than 0 * @param[out] out_fds Array of file descriptors to populate. Must not be null. * @param[in] fd_count Number of elements to receive into @p out_fds, must be * greater than 0 and must match the value provided at the * other end. * * @public @memberof ipc_message_channel */ xrt_result_t ipc_receive_fds(struct ipc_message_channel *imc, void *out_data, size_t size, int *out_fds, uint32_t fd_count); /*! * Send a message along with file descriptors over the IPC channel. * * @param imc Message channel to use * @param[in] data Pointer to the data buffer to send. Must not be * null: use a filler message if necessary. * @param[in] size Size of data pointed-to by @p data, must be greater than 0. * @param[out] fds Array of file descriptors to send. Must not benull. * @param[in] fd_count Number of elements in @p fds, must be greater than 0. If * this is variable, it must also be separately transmitted * ahead of time, because the receiver must have the same * value in its receive call. * * @public @memberof ipc_message_channel */ xrt_result_t ipc_send_fds(struct ipc_message_channel *imc, const void *data, size_t size, const int *fds, uint32_t fd_count); #elif defined(XRT_OS_WINDOWS) /*! * Receive a message along with a known number of file HANDLEs over the IPC * channel. * * @param imc Message channel to use * @param[out] out_data Pointer to the buffer to fill with data. Must not be * null. * @param[in] size Maximum size to read, must be greater than 0 * @param[out] out_handles Array of file HANDLEs to populate. Must not be * null. * @param[in] handle_count Number of elements to receive into @p out_handles, * must be greater than 0 and must match the value provided at the other end. * * @public @memberof ipc_message_channel */ xrt_result_t ipc_receive_handles( struct ipc_message_channel *imc, void *out_data, size_t size, HANDLE *out_handles, uint32_t handle_count); /*! * Send a message along with file HANDLEs over the IPC channel. * * @param imc Message channel to use * @param[in] data Pointer to the data buffer to send. Must not be * null: use a filler message if necessary. * @param[in] size Size of data pointed-to by @p data, must be greater than 0 * @param[out] handles Array of file HANDLEs to send. Must not be * null. * @param[in] handle_count Number of elements in @p handles, must be greater * than 0. If this is variable, it must also be separately transmitted ahead of * time, because the receiver must have the same value in its receive call. * * @public @memberof ipc_message_channel */ xrt_result_t ipc_send_handles( struct ipc_message_channel *imc, const void *data, size_t size, const HANDLE *handles, uint32_t handle_count); #endif // XRT_OS_UNIX /*! * @} */ /*! * @name Shared memory handle utilities * @brief Send/receive shared memory handles along with scalar/aggregate message * data. * @{ */ /*! * Receive a message along with a known number of shared memory handles over the * IPC channel. * * @param imc Message channel to use * @param[out] out_data Pointer to the buffer to fill with data. Must not be * null. * @param[in] size Maximum size to read, must be greater than 0 * @param[out] out_handles Array of shared memory handles to populate. Must not * be null. * @param[in] handle_count Number of elements to receive into @p out_handles, * must be greater than 0 and must match the value provided at the other end. * * @public @memberof ipc_message_channel * @see xrt_shmem_handle_t */ xrt_result_t ipc_receive_handles_shmem(struct ipc_message_channel *imc, void *out_data, size_t size, xrt_shmem_handle_t *out_handles, uint32_t handle_count); /*! * Send a message along with shared memory handles over the IPC channel. * * @param imc Message channel to use * @param[in] data Pointer to the data buffer to send. Must not be * null: use a filler message if necessary. * @param[in] size Size of data pointed-to by @p data, must be greater than 0 * @param[out] handles Array of shared memory handles to send. Must not be * null. * @param[in] handle_count Number of elements in @p handles, must be greater * than 0. If this is variable, it must also be separately transmitted ahead of * time, because the receiver must have the same value in its receive call. * * @public @memberof ipc_message_channel * @see xrt_shmem_handle_t */ xrt_result_t ipc_send_handles_shmem(struct ipc_message_channel *imc, const void *data, size_t size, const xrt_shmem_handle_t *handles, uint32_t handle_count); /*! * @} */ /*! * @name Graphics buffer handle utilities * @brief Send/receive graphics buffer handles along with scalar/aggregate * message data. * @{ */ /*! * Receive a message along with a known number of graphics buffer handles over * the IPC channel. * * @param imc Message channel to use * @param[out] out_data Pointer to the buffer to fill with data. Must not be * null. * @param[in] size Maximum size to read, must be greater than 0 * @param[out] out_handles Array of graphics buffer handles to populate. Must * not be null. * @param[in] handle_count Number of elements to receive into @p out_handles, * must be greater than 0 and must match the value provided at the other end. * * @public @memberof ipc_message_channel * @see xrt_graphics_buffer_handle_t */ xrt_result_t ipc_receive_handles_graphics_buffer(struct ipc_message_channel *imc, void *out_data, size_t size, xrt_graphics_buffer_handle_t *out_handles, uint32_t handle_count); /*! * Send a message along with native graphics buffer handles over the IPC * channel. * * @param imc Message channel to use * @param[in] data Pointer to the data buffer to send. Must not be * null: use a filler message if necessary. * @param[in] size Size of data pointed-to by @p data, must be greater than 0 * @param[out] handles Array of graphics buffer handles to send. Must not be * null. * @param[in] handle_count Number of elements in @p handles, must be greater * than 0. If this is variable, it must also be separately transmitted ahead of * time, because the receiver must have the same value in its receive call. * * @public @memberof ipc_message_channel * @see xrt_graphics_buffer_handle_t */ xrt_result_t ipc_send_handles_graphics_buffer(struct ipc_message_channel *imc, const void *data, size_t size, const xrt_graphics_buffer_handle_t *handles, uint32_t handle_count); /*! * @} */ /*! * @name Graphics buffer handle utilities * @brief Send/receive graphics buffer handles along with scalar/aggregate * message data. * @{ */ /*! * Receive a message along with a known number of graphics sync handles over * the IPC channel. * * @param imc Message channel to use * @param[out] out_data Pointer to the sync to fill with data. Must not be null. * @param[in] size Maximum size to read, must be greater than 0 * @param[out] out_handles Array of graphics sync handles to populate. Must not * be null. * @param[in] handle_count Number of elements to receive into @p out_handles, * must be greater than 0 and must match the value provided at the other end. * * @public @memberof ipc_message_channel * @see xrt_graphics_sync_handle_t */ xrt_result_t ipc_receive_handles_graphics_sync(struct ipc_message_channel *imc, void *out_data, size_t size, xrt_graphics_sync_handle_t *out_handles, uint32_t handle_count); /*! * Send a message along with native graphics sync handles over the IPC channel. * * @param imc Message channel to use * @param[in] data Pointer to the data sync to send. Must not be null: use a * filler message if necessary. * @param[in] size Size of data pointed-to by @p data, must be greater than 0 * @param[out] handles Array of graphics sync handles to send. Must not be * null. * @param[in] handle_count Number of elements in @p handles, must be greater than * 0. If this is variable, it must also be separately transmitted ahead of time, * because the receiver must have the same value in its receive call. * * @public @memberof ipc_message_channel * @see xrt_graphics_sync_handle_t */ xrt_result_t ipc_send_handles_graphics_sync(struct ipc_message_channel *imc, const void *data, size_t size, const xrt_graphics_sync_handle_t *handles, uint32_t handle_count); /*! * @} */ #ifdef __cplusplus } #endif