Source browser/Examples
C++ · complete file

06_sync_writer.cpp

Run the callback in the producer thread before write returns.

examples/two_buf_queue/06_sync_writer.cpp
49 lines2.8 KiBClick a line number to link to it
06_sync_writer.cpp
1// Synchronous callbacks run in the producer thread without a reader thread, which is useful for debugging.2// The rest matches asynchronous usage; specify the callback context when constructing the writer: make_writer<Writer<1, true, std::uint16_t, Context>>().3// With multiple writers/producer threads, the callback is automatically protected by a lock.4#include "../example_support.hpp"5#include <cstring>6using namespace TwoBufQueue;78int main() try {9    struct CustomData { int Data; };1011    //---------------1. Initialization--------------------------------------12    std::size_t count = 0;13    const auto writer_thread = std::this_thread::get_id();14    bool same_thread = true;1516    // Consumer callback.17    auto rcvCallback = [&](std::int32_t thread_id, const std::byte* data, std::size_t size) noexcept -> void {18        same_thread &= thread_id == 0 && std::this_thread::get_id() == writer_thread;19        if (++count <= 3) {20            std::printf("message: len = %.*s\n", static_cast<int>(size), reinterpret_cast<const char*>(data));21        } else {// No fixed payload type: decode according to the application's format.22            int type = 0;23            std::memcpy(&type, data, sizeof(type));24            std::printf("message: len = %d, type = %d\n", static_cast<int>(size), type);25        }26    };2728    // A non-void Context selects synchronous handling. The callback type remains inlineable; TwoBufQueue selects locking from the Writer count.29    using Context = SyncContext<decltype(rcvCallback)>;30    auto writer = make_writer<Writer<1, true, std::uint16_t, Context>>(); // Only the Context template argument differs here.31    ::TwoBufQueue::TwoBufQueue queue(rcvCallback, writer); // Bind the callback during construction; do not start a reader thread.3233    //---------------2. Producer writes-------------------------------------34    bool written = true;35    for (std::string_view text : {"hello", "TwoBufQueue", "goodbye"})36        written &= writer.write_mem(text.data(), static_cast<std::uint16_t>(text.size()));3738    // No fixed payload type: the consumer callback decodes the received data using the application's format.39    written &= writer.write(1, 1, static_cast<short>(2));40    written &= writer.write(2, CustomData{3});4142    //---------------3. Finish----------------------------------------------43    writer.finish(); // The application finishes the producer using the existing implementation.44    queue.stop();    // write has already handled each message; this returns the empty source block.4546    //---------------4. Check the result------------------------------------47    example::require(written && count == 5 && same_thread, "write/drain or message count mismatch");48    std::puts("PASS: 5 messages, callback on writer thread");49} catch (const std::exception& error) { std::fprintf(stderr, "%s\n", error.what()); return 1; }

Continue reading

TwoBufQueue · Full guideTwoBufQueue · Full guide (Chinese)API usage guideAPI usage guide (Chinese)ExamplesExamples (Chinese)