Unlike the Python bindings, the C++ bindings expose two heap types: live heaps (:cppspead2::recv::live_heap
) are used for heaps being constructed, and may be missing data; frozen heaps (:cppspead2::recv::heap
) always have all their data. Frozen heaps can be move-constructed from live heaps, which will typically be done in the callback.
spead2::recv::live_heap
spead2::recv::heap
spead2::recv::item
spead2::descriptor
At the lowest level, heaps are given to the application via a callback to a virtual function. While this callback is running, no new packets can be received from the network socket, so this function needs to complete quickly to avoid data loss when using UDP. To use this interface, subclass :cppspead2::recv::stream
and implement :cppheap_ready
and optionally override :cppstop_received
.
spead2::recv::stream
A potentially more convenient interface is :cppspead2::recv::ring_stream\<Ringbuffer>
, which places received heaps into a fixed-size thread-safe ring buffer. Another thread can then pull from this ring buffer in a loop. The template parameter selects the ringbuffer implementation. The default is a good light-weight choice, but if you need to use :cppselect
-like functions to wait for data, you can use :cppspead2::ringbuffer\<spead2::recv::live_heap, spead2::semaphore_fd, spead2::semaphore>
.
spead2::recv::ring_stream
Reader classes are constructed inside a stream by calling :cppspead2::recv::stream::emplace_reader
.
spead2::recv::udp_reader
spead2::recv::mem_reader
In addition to the memory allocators described in py-memory-allocators
, new allocators can be created by subclassing :cppspead2::memory_allocator
. For an allocator set on a stream, a pointer to a :cppspead2::recv::packet_header
is passed as a hint to the allocator, allowing memory to be placed according to information in the packet. Note that this can be any packet from the heap, so you must not rely on it being the initial packet.
spead2::memory_allocator