5 Rules
Upipe also defines semantic rules to correctly use the syntactic structures described in the previous chapters.
5.1 Pipes
The following rules apply to struct upipe:
All methods of struct upipe must be called from the same thread. As an exception, it is possible to allocate and configure a pipe in one thread, and migrate it to another thread afterwards, but a pipe is not required to be reentrant, nor to handle memory protection. This also applies to input and output subpipes of a pipe, which run in the same thread as the pipe. Also, for the same reason, it is not recommended to create loops in the dataflow.
A struct upipe shall throw upipe_throw_ready as soon as it is ready to receive inputs and control commands, and before sending any other probe, including log messages.
A struct upipe shall throw upipe_throw_dead when it does no longer wish to receive inputs and control commands; it shall not send any other probe afterwards, including log messages.
A struct upipe throwing upipe_throw_fatal shall no longer receive any input nor control command; it may only be released.
Only one pipe at time may call upipe_input on a given struct upipe. Pipes are not required to support multiple inputs. If multiple inputs are needed, they should be created using upipe_void_alloc_sub or upipe_flow_alloc_sub.
A struct upipe may only send its output to one pipe. If multiple outputs are needed, they should be created using upipe_flow_alloc_sub or upipe_void_alloc_sub (and it is up to the pipe to decide which packets to send where).
A struct upipe shall not use a blocking system call. It should register a file descriptor or a timer with upump_alloc_fd_read, upump_alloc_fd_write, or upump_alloc_timer.
The struct upump passed to upipe_input is only valid for the time of execution of upipe_input, and mustn't be kept by any downstream pipe. If blocking is desired, upump_blocker_alloc should be used.
The struct uref passed to upipe_input belongs to the callee, and must be freed at some point.
All parameters to upipe_control belong to the caller. The struct upipe must either duplicate or use (increment the refcount) structures it wants to keep. However if the control command is supposed to return information (such as control structures) from the struct upipe, the structure belongs to the callee and should be duplicated or used, if required, by the caller.
A pipe shall not throw a UPROBE_NEED_UPUMP_MGR event before receiving its first buffer, being sent UPIPE_ATTACH_UPUMP_MGR or being registered a struct urequest. An exception is allowed for source pipes, but it is legal for the application to not give a upump_mgr right away, and the source pipe should not throw a fatal error if that happens.
5.2 Probes
A struct uprobe must be called from the same thread as the struct upipe throwing the event; it is not required to be reentrant, nor to handle memory protection, but may opt to do so.
A struct uprobe shall not send control commands upon receiving a log event. Sending control commands from a probe is also discouraged.
The next probe pointer passed upon initializing a new probe belongs to the new probe, and should not be reused by the caller unless uprobe_use is called.
All parameters sent to the uprobe_throw function declared by probes belong to the calling pipe and should not be stored by the callees.
5.3 Buffers
ubuf_block_alloc shall not return a segmented block, ie. subsequent calls to ubuf_block_read or ubuf_block_write shall return the entire memory area.