Pipe convenience module. More...
#include <furi.h>
#include <stddef.h>
Go to the source code of this file.
Data Structures | |
struct | PipeSideBundle |
struct | PipeSideReceiveSettings |
Typedefs | |
typedef struct PipeSide | PipeSide |
typedef void(* | PipeSideDataArrivedCallback) (PipeSide *pipe, void *context) |
Callback for when data arrives to a PipeSide . | |
typedef void(* | PipeSideSpaceFreedCallback) (PipeSide *pipe, void *context) |
Callback for when data is read out of the opposite PipeSide . | |
typedef void(* | PipeSideBrokenCallback) (PipeSide *pipe, void *context) |
Callback for when the opposite PipeSide is freed, making the pipe broken. | |
Enumerations | |
enum | PipeRole { PipeRoleAlice , PipeRoleBob } |
The role of a pipe side. More... | |
enum | PipeState { PipeStateOpen , PipeStateBroken } |
The state of a pipe. More... | |
Functions | |
PipeSideBundle | pipe_alloc (size_t capacity, size_t trigger_level) |
Allocates two connected sides of one pipe. | |
PipeSideBundle | pipe_alloc_ex (PipeSideReceiveSettings alice, PipeSideReceiveSettings bob) |
Allocates two connected sides of one pipe. | |
PipeRole | pipe_role (PipeSide *pipe) |
Gets the role of a pipe side. | |
PipeState | pipe_state (PipeSide *pipe) |
Gets the state of a pipe. | |
void | pipe_free (PipeSide *pipe) |
Frees a side of a pipe. | |
void | pipe_install_as_stdio (PipeSide *pipe) |
Connects the pipe to the stdin and stdout of the current thread. | |
size_t | pipe_receive (PipeSide *pipe, void *data, size_t length, FuriWait timeout) |
Receives data from the pipe. | |
size_t | pipe_send (PipeSide *pipe, const void *data, size_t length, FuriWait timeout) |
Sends data into the pipe. | |
size_t | pipe_bytes_available (PipeSide *pipe) |
Determines how many bytes there are in the pipe available to be read. | |
size_t | pipe_spaces_available (PipeSide *pipe) |
Determines how many space there is in the pipe for data to be written into. | |
void | pipe_attach_to_event_loop (PipeSide *pipe, FuriEventLoop *event_loop) |
Attaches a PipeSide to a FuriEventLoop , allowing to attach callbacks to the PipeSide. | |
void | pipe_detach_from_event_loop (PipeSide *pipe) |
Detaches a PipeSide from the FuriEventLoop that it was previously attached to. | |
void | pipe_set_callback_context (PipeSide *pipe, void *context) |
Sets the custom context for all callbacks. | |
void | pipe_set_data_arrived_callback (PipeSide *pipe, PipeSideDataArrivedCallback callback, FuriEventLoopEvent event) |
Sets the callback for when data arrives. | |
void | pipe_set_space_freed_callback (PipeSide *pipe, PipeSideSpaceFreedCallback callback, FuriEventLoopEvent event) |
Sets the callback for when data is read out of the opposite PipeSide . | |
void | pipe_set_broken_callback (PipeSide *pipe, PipeSideBrokenCallback callback, FuriEventLoopEvent event) |
Sets the callback for when the opposite PipeSide is freed, making the pipe broken. | |
Pipe convenience module.
Pipes are used to send bytes between two threads in both directions. The two threads are referred to as Alice and Bob and their abilities regarding what they can do with the pipe are equal.
It is also possible to use both sides of the pipe within one thread.
typedef void(* PipeSideBrokenCallback) (PipeSide *pipe, void *context) |
Callback for when the opposite PipeSide
is freed, making the pipe broken.
[in] | pipe | Pipe side that called the callback |
[in,out] | context | Custom context |
typedef void(* PipeSideDataArrivedCallback) (PipeSide *pipe, void *context) |
Callback for when data arrives to a PipeSide
.
[in] | pipe | Pipe side that called the callback |
[in,out] | context | Custom context |
typedef void(* PipeSideSpaceFreedCallback) (PipeSide *pipe, void *context) |
Callback for when data is read out of the opposite PipeSide
.
[in] | pipe | Pipe side that called the callback |
[in,out] | context | Custom context |
enum PipeRole |
The role of a pipe side.
Both roles are equal, as they can both read and write the data. This status might be helpful in determining the role of a thread w.r.t. another thread in an application that builds on the pipe.
enum PipeState |
The state of a pipe.
PipeStateOpen
: Both pipe sides are in place, meaning data that is sent down the pipe might be read by the peer, and new data sent by the peer might arrive.PipeStateBroken
: The other side of the pipe has been freed, meaning data that is written will never reach its destination, and no new data will appear in the buffer.A broken pipe can never become open again, because there's no way to connect a side of a pipe to another side of a pipe.
PipeSideBundle pipe_alloc | ( | size_t | capacity, |
size_t | trigger_level ) |
Allocates two connected sides of one pipe.
Creating a pair of sides using this function is the only way to connect two pipe sides together. Two unrelated orphaned sides may never be connected back together.
The capacity and trigger level for both directions are the same when the pipe is created using this function. Use pipe_alloc_ex
if you want more control.
capacity | Maximum number of bytes buffered in one direction |
trigger_level | Number of bytes that need to be available in the buffer in order for a blocked thread to unblock |
PipeSideBundle pipe_alloc_ex | ( | PipeSideReceiveSettings | alice, |
PipeSideReceiveSettings | bob ) |
Allocates two connected sides of one pipe.
Creating a pair of sides using this function is the only way to connect two pipe sides together. Two unrelated orphaned sides may never be connected back together.
The capacity and trigger level may be different for the two directions when the pipe is created using this function. Use pipe_alloc
if you don't need control this fine.
alice | capacity and trigger_level settings for Alice's receiving buffer |
bob | capacity and trigger_level settings for Bob's receiving buffer |
void pipe_attach_to_event_loop | ( | PipeSide * | pipe, |
FuriEventLoop * | event_loop ) |
Attaches a PipeSide
to a FuriEventLoop
, allowing to attach callbacks to the PipeSide.
[in] | pipe | Pipe side to attach to the event loop |
[in] | event_loop | Event loop to attach the pipe side to |
size_t pipe_bytes_available | ( | PipeSide * | pipe | ) |
Determines how many bytes there are in the pipe available to be read.
[in] | pipe | Pipe side to query |
void pipe_detach_from_event_loop | ( | PipeSide * | pipe | ) |
Detaches a PipeSide
from the FuriEventLoop
that it was previously attached to.
[in] | pipe | Pipe side to detach to the event loop |
void pipe_free | ( | PipeSide * | pipe | ) |
Frees a side of a pipe.
When only one of the sides is freed, the pipe is transitioned from the "Open" state into the "Broken" state. When both sides are freed, the underlying data structures are freed too.
[in] | pipe | Pipe side to free |
void pipe_install_as_stdio | ( | PipeSide * | pipe | ) |
Connects the pipe to the stdin
and stdout
of the current thread.
After performing this operation, you can use getc
, puts
, etc. to send and receive data to and from the pipe. If the pipe becomes broken, C stdlib calls will return EOF
wherever possible.
You can disconnect the pipe by manually calling furi_thread_set_stdout_callback
and furi_thread_set_stdin_callback
with NULL
.
[in] | pipe | Pipe side to connect to the stdio |
size_t pipe_receive | ( | PipeSide * | pipe, |
void * | data, | ||
size_t | length, | ||
FuriWait | timeout ) |
Receives data from the pipe.
[in] | pipe | The pipe side to read data out of |
[out] | data | The buffer to fill with data |
length | Maximum length of data to read | |
timeout | The timeout (in ticks) after which the read operation is interrupted |
Gets the role of a pipe side.
The roles (Alice and Bob) are equal, as both can send and receive data. This status might be helpful in determining the role of a thread w.r.t. another thread.
[in] | pipe | Pipe side to query |
size_t pipe_send | ( | PipeSide * | pipe, |
const void * | data, | ||
size_t | length, | ||
FuriWait | timeout ) |
Sends data into the pipe.
[in] | pipe | The pipe side to send data into |
[out] | data | The buffer to get data from |
length | Maximum length of data to send | |
timeout | The timeout (in ticks) after which the write operation is interrupted |
void pipe_set_broken_callback | ( | PipeSide * | pipe, |
PipeSideBrokenCallback | callback, | ||
FuriEventLoopEvent | event ) |
Sets the callback for when the opposite PipeSide
is freed, making the pipe broken.
[in] | pipe | Pipe side to assign the callback to |
[in] | callback | Callback to assign to the pipe side. Set to NULL to unsubscribe. |
[in] | event | Additional event loop flags (e.g. Edge , Once , etc.). Non-flag values of the enum are not allowed. |
pipe_attach_to_event_loop
. void pipe_set_callback_context | ( | PipeSide * | pipe, |
void * | context ) |
Sets the custom context for all callbacks.
[in] | pipe | Pipe side to set the context of |
[in,out] | context | Custom context that will be passed to callbacks |
void pipe_set_data_arrived_callback | ( | PipeSide * | pipe, |
PipeSideDataArrivedCallback | callback, | ||
FuriEventLoopEvent | event ) |
Sets the callback for when data arrives.
[in] | pipe | Pipe side to assign the callback to |
[in] | callback | Callback to assign to the pipe side. Set to NULL to unsubscribe. |
[in] | event | Additional event loop flags (e.g. Edge , Once , etc.). Non-flag values of the enum are not allowed. |
pipe_attach_to_event_loop
. void pipe_set_space_freed_callback | ( | PipeSide * | pipe, |
PipeSideSpaceFreedCallback | callback, | ||
FuriEventLoopEvent | event ) |
Sets the callback for when data is read out of the opposite PipeSide
.
[in] | pipe | Pipe side to assign the callback to |
[in] | callback | Callback to assign to the pipe side. Set to NULL to unsubscribe. |
[in] | event | Additional event loop flags (e.g. Edge , Once , etc.). Non-flag values of the enum are not allowed. |
pipe_attach_to_event_loop
. size_t pipe_spaces_available | ( | PipeSide * | pipe | ) |
Determines how many space there is in the pipe for data to be written into.
[in] | pipe | Pipe side to query |
Gets the state of a pipe.
When the state is PipeStateOpen
, both sides are active and may send or receive data. When the state is PipeStateBroken
, only one side is active (the one that this method has been called on). If you find yourself in that state, the data that you send will never be heard by anyone, and the data you receive are leftovers in the buffer.
[in] | pipe | Pipe side to query |