From 9768ee6392ee515ad2371a2bb5662011c9a87941 Mon Sep 17 00:00:00 2001 From: Samuel Sadok Date: Fri, 8 Jan 2021 11:35:26 +0100 Subject: [PATCH] Squashed 'Firmware/fibre-cpp/' changes from 767bcb32..d7049207 d7049207 use docker for CI a66a4815 fix various bugs git-subtree-dir: Firmware/fibre-cpp git-subtree-split: d7049207dc53aa87f6903e0f60f7904429164f6e --- Dockerfile | 3 ++ README.md | 2 +- Tupfile.lua | 18 ++++++++-- channel_discoverer.cpp | 2 +- configs/linux-amd64.config | 3 +- configs/linux-armhf.config | 1 + configs/macos-x86.config | 1 + configs/wasm.config | 1 + configs/windows-amd64.config | 1 + endpoints_template.j2 | 1 + fibre.cpp | 20 +++++++++-- include/fibre/cpp_utils.hpp | 3 ++ include/fibre/fibre.hpp | 6 ++-- interfaces_template.j2 | 6 ++-- legacy_object_client.cpp | 1 + legacy_object_client.hpp | 4 ++- legacy_protocol.cpp | 50 +++++++++++++++++++-------- legacy_protocol.hpp | 2 ++ libfibre.cpp | 6 ++-- package.lua | 12 ++++--- platform_support/libusb_transport.cpp | 5 +-- platform_support/libusb_transport.hpp | 4 +-- platform_support/posix_socket.cpp | 4 +-- platform_support/posix_socket.hpp | 2 +- stream_utils.hpp | 28 +++++++-------- type_info_template.j2 | 4 +-- 26 files changed, 128 insertions(+), 62 deletions(-) diff --git a/Dockerfile b/Dockerfile index 212b779c..13378bb5 100644 --- a/Dockerfile +++ b/Dockerfile @@ -47,6 +47,9 @@ RUN mkdir -p "third_party/libusb-windows" && \ # Make Emscripten build its standard libraries for the WebAssembly target RUN echo "void test() {}" | em++ -x c - -o /tmp/a.out +# Install dependencies for interface_generator.py +RUN pacman -S --noconfirm python-yaml python-jinja python-jsonschema + ENV THIRD_PARTY=/ # Set up entrypoint diff --git a/README.md b/README.md index 85493c94..32ab5990 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # fibre-cpp -This directory provides the C/C++ reference implementation of [Fibre](https://github.com/samuelsadok/fibre). Its home is located [here](https://github.com/samuelsadok/fibre/tree/master/cpp). There's also a standalone repository for this directory [here](https://github.com/samuelsadok/fibre-cpp). +This directory provides the C++ reference implementation of [Fibre](https://github.com/samuelsadok/fibre). Its home is located [here](https://github.com/samuelsadok/fibre/tree/master/cpp). There's also a standalone repository for this directory [here](https://github.com/samuelsadok/fibre-cpp). ## Overview diff --git a/Tupfile.lua b/Tupfile.lua index 592ff462..f0575a35 100644 --- a/Tupfile.lua +++ b/Tupfile.lua @@ -1,7 +1,14 @@ +-- Projects that include fibre-cpp and also use tup can place a Tuprules.lua file +-- into their root directory with the line `no_libfibre = true` to prevent +-- libfibre from building. +if no_libfibre == true then + return +end + tup.include('package.lua') -CFLAGS = {'-fPIC -std=c++11 -DFIBRE_COMPILE'} +CFLAGS = {'-fPIC -std=c++11 -DFIBRE_COMPILE -Wall'} LDFLAGS = {'-static-libstdc++'} @@ -28,8 +35,9 @@ end CFLAGS += tup.getconfig("CFLAGS") LDFLAGS += tup.getconfig("LDFLAGS") DEBUG = get_bool_config("DEBUG", true) +STRICT = get_bool_config("STRICT", false) -machine = run_now(CXX..' -dumpmachine') -- works with both clang and GCC +machine = fibre_run_now(CXX..' -dumpmachine') -- works with both clang and GCC BUILD_TYPE='-shared' @@ -64,6 +72,10 @@ else CFLAGS += '-O3' -- TODO: add back -lfto end +if STRICT then + CFLAGS += '-Werror' +end + function compile(src_file) obj_file = 'build/'..tup.file(src_file)..'.o' tup.frule{ @@ -81,7 +93,7 @@ pkg = get_fibre_package({ enable_tcp_client_backend=get_bool_config("ENABLE_TCP_CLIENT_BACKEND", true), enable_libusb_backend=get_bool_config("ENABLE_LIBUSB_BACKEND", true), allow_heap=true, - pkgconf=tup.getconfig("USE_PKGCONF") or nil + pkgconf=(tup.getconfig("USE_PKGCONF") != "") and tup.getconfig("USE_PKGCONF") or nil }) CFLAGS += pkg.cflags diff --git a/channel_discoverer.cpp b/channel_discoverer.cpp index 9556e4d4..8411868d 100644 --- a/channel_discoverer.cpp +++ b/channel_discoverer.cpp @@ -7,7 +7,7 @@ using namespace fibre; bool ChannelDiscoverer::try_parse_key(const char* begin, const char* end, const char* key, const char** val_begin, const char** val_end) { - size_t keylen = strlen(key); + ssize_t keylen = strlen(key); while (begin != end) { const char* next_delim = std::find(begin, end, ','); diff --git a/configs/linux-amd64.config b/configs/linux-amd64.config index 7bb868ed..06bc2d83 100644 --- a/configs/linux-amd64.config +++ b/configs/linux-amd64.config @@ -1,5 +1,6 @@ CONFIG_DEBUG=false +CONFIG_STRICT=true CONFIG_CC="clang++" CONFIG_CFLAGS="-I$THIRD_PARTY./third_party/libusb-dev-armhf/usr/include/libusb-1.0" -CONFIG_LDFLAGS="-L$THIRD_PARTY./third_party/libusb-amd64/lib/x86_64-linux-gnu/libusb-1.0.so.0.2.0" +CONFIG_LDFLAGS="$THIRD_PARTY./third_party/libusb-amd64/lib/x86_64-linux-gnu/libusb-1.0.so.0.2.0" CONFIG_USE_PKGCONF=false diff --git a/configs/linux-armhf.config b/configs/linux-armhf.config index 04c427ba..7b684f89 100644 --- a/configs/linux-armhf.config +++ b/configs/linux-armhf.config @@ -1,4 +1,5 @@ CONFIG_DEBUG=false +CONFIG_STRICT=true CONFIG_CC="arm-linux-gnueabihf-g++" CONFIG_CFLAGS="-I$THIRD_PARTY./third_party/libusb-dev-armhf/usr/include/libusb-1.0" CONFIG_LDFLAGS="-L$THIRD_PARTY./third_party/libstdc++-linux-armhf/usr/lib/gcc-cross/arm-linux-gnueabihf/10 $THIRD_PARTY./third_party/libusb-armhf/usr/lib/arm-linux-gnueabihf/libusb-1.0.so.0" diff --git a/configs/macos-x86.config b/configs/macos-x86.config index 9e930262..4e9afec4 100644 --- a/configs/macos-x86.config +++ b/configs/macos-x86.config @@ -1,4 +1,5 @@ CONFIG_DEBUG=false +CONFIG_STRICT=true CONFIG_CC="LD_LIBRARY_PATH=/opt/osxcross/lib MACOSX_DEPLOYMENT_TARGET=10.9 /opt/osxcross/bin/o64-clang++" CONFIG_CFLAGS="-I$THIRD_PARTY./third_party/libusb-1.0.23/libusb -arch i386 -arch x86_64" CONFIG_LDFLAGS="$THIRD_PARTY./third_party/libusb-1.0.23/build-macos-amd64/libusb/.libs/libusb-1.0.a -framework CoreFoundation -framework IOKit" diff --git a/configs/wasm.config b/configs/wasm.config index 948a0e7e..6a683e2d 100644 --- a/configs/wasm.config +++ b/configs/wasm.config @@ -1,4 +1,5 @@ CONFIG_DEBUG=true +CONFIG_STRICT=true CONFIG_CC=/usr/lib/emscripten/em++ CONFIG_CFLAGS=-include emscripten.h -DFIBRE_PUBLIC=EMSCRIPTEN_KEEPALIVE -s RESERVED_FUNCTION_POINTERS=1 CONFIG_LDFLAGS=-s EXPORT_ES6=1 -s MODULARIZE=1 -s USE_ES6_IMPORT_META=0 -s 'EXTRA_EXPORTED_RUNTIME_METHODS=[addFunction, stringToUTF8Array, UTF8ArrayToString, ENV]' diff --git a/configs/windows-amd64.config b/configs/windows-amd64.config index 423cfcb1..2b26e9b5 100644 --- a/configs/windows-amd64.config +++ b/configs/windows-amd64.config @@ -1,4 +1,5 @@ CONFIG_DEBUG=false +CONFIG_STRICT=true CONFIG_CC="x86_64-w64-mingw32-g++" CONFIG_CFLAGS="-I$THIRD_PARTY./third_party/libusb-windows/libusb-1.0.23/include/libusb-1.0" CONFIG_LDFLAGS="-static-libgcc $THIRD_PARTY./third_party/libusb-windows/libusb-1.0.23/MinGW64/static/libusb-1.0.a" diff --git a/endpoints_template.j2 b/endpoints_template.j2 index 4e467894..459a2ca2 100644 --- a/endpoints_template.j2 +++ b/endpoints_template.j2 @@ -15,6 +15,7 @@ #include #include +#include // Note: with -Og the functions with large switch statements reserves a huge amount // of stack space because they reserves separate space for the stack frame of each diff --git a/fibre.cpp b/fibre.cpp index 81a15f4b..a024ec59 100644 --- a/fibre.cpp +++ b/fibre.cpp @@ -6,6 +6,7 @@ #include "print_utils.hpp" #include #include +#include #if FIBRE_ALLOW_HEAP #include @@ -102,6 +103,17 @@ struct BackendDeinitializer { Context* ctx; }; +template +bool all(std::tuple args, std::index_sequence) { + std::array arr = { std::get(args) ... }; + return std::all_of(arr.begin(), arr.end(), [](bool val) { return val; }); +} + +template +bool all(std::tuple args) { + return all(args, std::make_index_sequence()); +} + Context* fibre::open(EventLoop* event_loop) { Context* ctx = my_alloc(); if (!ctx) { @@ -115,9 +127,9 @@ Context* fibre::open(EventLoop* event_loop) { // TODO: check static_backends_good - //if (std::all(static_backends_good)) { - // return nullptr; - //} + if (all(static_backends_good)) { + return nullptr; + } return ctx; } @@ -133,6 +145,7 @@ void fibre::close(Context* ctx) { my_free(ctx); } +#if FIBRE_ALLOW_HEAP Domain* Context::create_domain(std::string specs) { FIBRE_LOG(D) << "creating domain with path \"" << specs << "\""; @@ -191,6 +204,7 @@ void Context::deregister_backend(std::string name) { discoverers.erase(it); } +#endif #if FIBRE_ENABLE_CLIENT void Domain::start_discovery(Callback on_found_object, Callback on_lost_object) { diff --git a/include/fibre/cpp_utils.hpp b/include/fibre/cpp_utils.hpp index 81aad20b..262598dd 100644 --- a/include/fibre/cpp_utils.hpp +++ b/include/fibre/cpp_utils.hpp @@ -528,6 +528,9 @@ optional make_optional(T& val) { } // namespace std +#else +#include +#include #endif /* Stuff that should be in the STL but isn't ---------------------------------*/ diff --git a/include/fibre/fibre.hpp b/include/fibre/fibre.hpp index 1aefd94f..b653d3f8 100644 --- a/include/fibre/fibre.hpp +++ b/include/fibre/fibre.hpp @@ -38,7 +38,7 @@ struct Function { struct Object; struct Interface; -struct Domain; +class Domain; template struct StaticBackend { @@ -87,11 +87,11 @@ struct Context { // TODO: don't declare these types here struct LegacyProtocolPacketBased; -struct LegacyObjectClient; +class LegacyObjectClient; struct LegacyObject; class Domain { - friend class Context; + friend struct Context; public: #if FIBRE_ENABLE_CLIENT // TODO: add interface argument diff --git a/interfaces_template.j2 b/interfaces_template.j2 index 3f186a71..7ca2ef30 100644 --- a/interfaces_template.j2 +++ b/interfaces_template.j2 @@ -12,6 +12,8 @@ #ifndef __FIBRE_INTERFACES_HPP #define __FIBRE_INTERFACES_HPP +[[userdata.c_preamble]] + #include #pragma GCC push_options @@ -28,7 +30,7 @@ std::tuple<[% for arg in func.out.values() %][[arg.type.c_name]][[', ' if not lo [%- endmacro %] [%- macro render_interface(intf) %] -class [[intf.name | to_pascal_case]]Intf { +class [[intf.name | to_pascal_case]]Intf[% if intf.implements %] :[%- for base_intf in intf.implements %] public [[base_intf.c_name]][% endfor %][% endif %] { public: [%- for intf in intf.interfaces -%] [[render_interface(intf) | indent(4)]] @@ -36,7 +38,7 @@ public: [%- for enum in intf.enums %] enum [[enum.name | to_pascal_case]] { [%- for k, value in enum['values'].items() %] - [[((enum.name + k) | to_macro_case).ljust(32)]] = [% if enum.is_flags %]0x[['%08x' | format(value.value)]][% else %][[value.value]][% endif %], + [[((enum.name | to_macro_case) + "_" + (k | to_macro_case)).ljust(32)]] = [% if enum.is_flags %]0x[['%08x' | format(value.value)]][% else %][[value.value]][% endif %], [%- endfor %] }; [%- endfor %] diff --git a/legacy_object_client.cpp b/legacy_object_client.cpp index af6bd6ce..9e0b1270 100644 --- a/legacy_object_client.cpp +++ b/legacy_object_client.cpp @@ -469,6 +469,7 @@ void LegacyCallContext::resume_from_protocol(EndpointOperationResult result) { ep_result = result; return; } + op_handle_ = 0; std::variant res = result; diff --git a/legacy_object_client.hpp b/legacy_object_client.hpp index cf54c5a4..c9d88e54 100644 --- a/legacy_object_client.hpp +++ b/legacy_object_client.hpp @@ -20,6 +20,8 @@ struct EndpointOperationResult { uint8_t* rx_end; }; +// Lower 16 bits are the seqno. Upper 16 bits are all 1 for valid handles +// (such that seqno 0 doesn't cause the handle to be 0) using EndpointOperationHandle = uint32_t; struct LegacyProtocolPacketBased; @@ -51,7 +53,7 @@ struct LegacyFunction : Function { }; struct FibreInterface; -struct LegacyObjectClient; +class LegacyObjectClient; struct LegacyFibreAttribute { std::shared_ptr object; diff --git a/legacy_protocol.cpp b/legacy_protocol.cpp index 27575704..39c6885e 100644 --- a/legacy_protocol.cpp +++ b/legacy_protocol.cpp @@ -273,7 +273,7 @@ void LegacyProtocolPacketBased::cancel_endpoint_operation(EndpointOperationHandl pending_operation_ = std::nullopt; } - auto it = expected_acks_.find(handle); + auto it = expected_acks_.find(seqno); if (it != expected_acks_.end()) { callback = it->second.callback; @@ -336,17 +336,26 @@ void LegacyProtocolPacketBased::on_write_finished(WriteResult result) { transmitting_op_ = 0; auto it = expected_acks_.find(seqno); + size_t n_sent = std::max((size_t)(result.end - tx_buf_), (size_t)8) - 8; it->second.tx_buf = it->second.tx_buf.skip(n_sent); + it->second.tx_done = true; - // If the TX task was a remote endpoint operation but didn't succeed - // we terminate that operation - if (result.status != kStreamOk) { - auto callback = it->second.callback; - auto tx_end = it->second.tx_buf.begin(); - auto rx_end = it->second.rx_buf.begin(); + if (it->second.rx_done) { + // It's possible that the RX operation completes before the TX operation + auto op = it->second; expected_acks_.erase(it); - callback.invoke_and_clear({result.status, result.end, rx_end}); + op.callback.invoke_and_clear({kStreamOk, op.tx_buf.begin(), op.rx_buf.begin()}); + } else if (result.status != kStreamOk) { + // If the TX task was a remote endpoint operation but didn't succeed + // we terminate that operation + auto op = it->second; + expected_acks_.erase(it); + op.callback.invoke_and_clear({result.status, result.end, op.rx_buf.begin()}); + } + + if (transmitting_op_) { + return; } } #endif @@ -360,7 +369,11 @@ void LegacyProtocolPacketBased::on_write_finished(WriteResult result) { uint8_t* rx_end = rx_end_; rx_end_ = nullptr; on_read_finished({kStreamOk, rx_end}); - return; +#if FIBRE_ENABLE_CLIENT + if (transmitting_op_) { + return; + } +#endif } #endif @@ -371,7 +384,9 @@ void LegacyProtocolPacketBased::on_write_finished(WriteResult result) { EndpointOperation op = *pending_operation_; pending_operation_ = std::nullopt; start_endpoint_operation(op); - return; + if (transmitting_op_) { + return; + } } #endif } @@ -415,11 +430,16 @@ void LegacyProtocolPacketBased::on_read_finished(ReadResult result) { } else { size_t n_copy = std::min((size_t)(result.end - rx_buf.begin()), it->second.rx_buf.size()); memcpy(it->second.rx_buf.begin(), rx_buf.begin(), n_copy); - const uint8_t* tx_end = it->second.tx_buf.begin(); - uint8_t* rx_end = it->second.rx_buf.begin() + n_copy; - auto callback = it->second.callback; - expected_acks_.erase(it); - callback.invoke_and_clear({kStreamOk, tx_end, rx_end}); + it->second.rx_buf = it->second.rx_buf.skip(n_copy); + it->second.rx_done = true; + FIBRE_LOG(T) << "received ACK: " << (*seq_no & 0x7fff); + + // It's possible that the RX operation completes before the TX operation + if (it->second.tx_done) { + auto op = it->second; + expected_acks_.erase(it); + op.callback.invoke_and_clear({kStreamOk, op.tx_buf.begin(), op.rx_buf.begin()}); + } } #else diff --git a/legacy_protocol.hpp b/legacy_protocol.hpp index d87223f3..43bffb53 100644 --- a/legacy_protocol.hpp +++ b/legacy_protocol.hpp @@ -126,7 +126,9 @@ private: uint16_t seqno; uint16_t endpoint_id; cbufptr_t tx_buf; + bool tx_done; bufptr_t rx_buf; + bool rx_done; Callback callback; }; diff --git a/libfibre.cpp b/libfibre.cpp index 9cb9a1e9..aca8fd25 100644 --- a/libfibre.cpp +++ b/libfibre.cpp @@ -12,7 +12,7 @@ USE_LOG_TOPIC(LIBFIBRE); static const struct LibFibreVersion libfibre_version = { 0, 1, 0 }; -class FIBRE_PRIVATE ExternalEventLoop : public fibre::EventLoop { +class FIBRE_PRIVATE ExternalEventLoop final : public fibre::EventLoop { public: ExternalEventLoop(LibFibreEventLoop impl) : impl_(impl) {} @@ -81,7 +81,7 @@ int ExternalDiscoverer::stop_channel_discovery(fibre::ChannelDiscoveryContext* h namespace fibre { -class AsyncStreamLink : public AsyncStreamSink, public AsyncStreamSource { +class AsyncStreamLink final : public AsyncStreamSink, public AsyncStreamSource { public: void start_write(cbufptr_t buffer, TransferHandle* handle, Callback completer) final; void cancel_write(TransferHandle transfer_handle) final; @@ -457,7 +457,7 @@ LibFibreStatus libfibre_get_attribute(LibFibreObject* parent_obj, LibFibreAttrib return kFibreInvalidArgument; } - LibFibreCtx* libfibre_ctx = reinterpret_cast(parent_obj_cast->client->user_data_); + //LibFibreCtx* libfibre_ctx = reinterpret_cast(parent_obj_cast->client->user_data_); fibre::LegacyObject* child_obj = attr_cast->object.get(); if (!attr_cast->object->known_to_application) { diff --git a/package.lua b/package.lua index 5bc98e98..599e85b0 100644 --- a/package.lua +++ b/package.lua @@ -1,4 +1,5 @@ +fibre_root = tup.getcwd() -- Returns a table that contains the Fibre code files and the flags required to -- compile and link those files. @@ -30,6 +31,7 @@ -- linking the object files. function get_fibre_package(args) pkg = { + root = fibre_root, code_files = { 'fibre.cpp', 'channel_discoverer.cpp', @@ -58,9 +60,11 @@ function get_fibre_package(args) end elseif args.pkgconf == false then + print("not using pkgconf") pkgconf_file = nil pkgconf = null_pkgconf else + print("using pkgconf: "..args.pkgconf) pkgconf_file = args.pkgconf pkgconf = real_pkgconf end @@ -108,7 +112,7 @@ end -- graph). -- Returns the values (return_code, stdout) where stdout has the trailing new -- line removed. -function run_now(command) +function fibre_run_now(command) local handle handle = io.popen(command) local output = handle:read("*a") @@ -117,13 +121,13 @@ function run_now(command) end function test_pkgconf(name) - local str, rc = run_now(name.." --version 2>&1 >/dev/null") + local str, rc = fibre_run_now(name.." --version 2>&1 >/dev/null") return rc end function real_pkgconf(pkg, lib) - pkg.cflags += run_now(pkgconf_file..' '..lib..' --cflags') - pkg.ldflags += run_now(pkgconf_file..' '..lib..' --libs') + pkg.cflags += fibre_run_now(pkgconf_file..' '..lib..' --cflags') + pkg.ldflags += fibre_run_now(pkgconf_file..' '..lib..' --libs') end function null_pkgconf(pkg, lib) diff --git a/platform_support/libusb_transport.cpp b/platform_support/libusb_transport.cpp index 2e5488a1..b3febc10 100644 --- a/platform_support/libusb_transport.cpp +++ b/platform_support/libusb_transport.cpp @@ -216,8 +216,6 @@ bool LibusbDiscoverer::deinit(int stage) { void LibusbDiscoverer::start_channel_discovery(const char* specs, size_t specs_len, ChannelDiscoveryContext** handle, Callback on_found_channels) { FIBRE_LOG(D) << "starting discovery with filter \"" << std::string(specs, specs_len) << "\""; - const char* prev_delim = specs; - InterfaceSpecs interface_specs; try_parse_key(specs, specs + specs_len, "bus", &interface_specs.bus); @@ -450,7 +448,6 @@ void LibusbDiscoverer::consider_device(struct libusb_device *device, MyChannelDi } } - static libusb_device_handle *handle = nullptr; struct libusb_config_descriptor* config_desc = nullptr; if (libusb_get_active_config_descriptor(device, &config_desc) != LIBUSB_SUCCESS) { @@ -645,7 +642,7 @@ void LibusbBulkEndpoint::on_transfer_finished() { ssize_t n_devices = libusb_get_device_list(parent_->libusb_ctx_, &list); if (n_devices >= 0) { - for (size_t i = 0; i < n_devices; ++i) { + for (size_t i = 0; i < (size_t)n_devices; ++i) { if (list[i] == dev) { break; } diff --git a/platform_support/libusb_transport.hpp b/platform_support/libusb_transport.hpp index 42416508..aaf86303 100644 --- a/platform_support/libusb_transport.hpp +++ b/platform_support/libusb_transport.hpp @@ -95,7 +95,7 @@ private: Callback completer_ = nullptr; }; -class LibusbBulkInEndpoint : public LibusbBulkEndpoint, public AsyncStreamSource { +class LibusbBulkInEndpoint final : public LibusbBulkEndpoint, public AsyncStreamSource { public: void start_read(bufptr_t buffer, TransferHandle* handle, Callback completer) final { start_transfer(buffer, handle, completer); @@ -106,7 +106,7 @@ public: } }; -class LibusbBulkOutEndpoint : public LibusbBulkEndpoint, public AsyncStreamSink { +class LibusbBulkOutEndpoint final : public LibusbBulkEndpoint, public AsyncStreamSink { public: void start_write(cbufptr_t buffer, TransferHandle* handle, Callback completer) final { start_transfer({ diff --git a/platform_support/posix_socket.cpp b/platform_support/posix_socket.cpp index 21d691e5..53475fca 100644 --- a/platform_support/posix_socket.cpp +++ b/platform_support/posix_socket.cpp @@ -409,7 +409,7 @@ std::optional PosixSocket::read_sync(bufptr_t buffer) { return {{kStreamError, buffer.end()}}; // the function might have written to the buffer } - } else if (n_received > buffer.size()) { + } else if ((size_t)n_received > buffer.size()) { FIBRE_LOG(E) << "received too many bytes"; return {{kStreamError, buffer.end()}}; @@ -441,7 +441,7 @@ std::optional PosixSocket::write_sync(cbufptr_t buffer) { return {{kStreamError, buffer.end()}}; // the function might have written to the buffer } - } else if (n_sent > buffer.size()) { + } else if ((size_t)n_sent > buffer.size()) { FIBRE_LOG(E) << "sent too many bytes"; return {{kStreamError, buffer.end()}}; diff --git a/platform_support/posix_socket.hpp b/platform_support/posix_socket.hpp index ed7151f2..457c1e63 100644 --- a/platform_support/posix_socket.hpp +++ b/platform_support/posix_socket.hpp @@ -107,7 +107,7 @@ void stop_listening(ConnectionContext* ctx); * * Note: To make this work on Windows, a "poll"-based worker must be implemented. */ -class PosixSocket : public AsyncStreamSource, public AsyncStreamSink { +class PosixSocket final : public AsyncStreamSource, public AsyncStreamSink { public: /** * @brief Initializes the object with the given socket ID. diff --git a/stream_utils.hpp b/stream_utils.hpp index 42f99740..681a521a 100644 --- a/stream_utils.hpp +++ b/stream_utils.hpp @@ -1,13 +1,13 @@ #ifndef __FIBRE_STREAM_UTILS_HPP #define __FIBRE_STREAM_UTILS_HPP -#include "async_stream.hpp" +#include #include namespace fibre { template -class BufferedStreamSink : Completer { +class BufferedStreamSink { public: BufferedStreamSink(AsyncStreamSink& sink) : sink_(sink) {} @@ -50,17 +50,17 @@ public: // nothing to do } else if (read_idx_ < write_idx_) { is_active_ = true; - sink_.start_write({buffer_ + read_idx_, buffer_ + write_idx_}, &transfer_handle_, *this); + sink_.start_write({buffer_ + read_idx_, buffer_ + write_idx_}, &transfer_handle_, MEMBER_CB(this, on_write_complete)); } else if (read_idx_ > write_idx_) { is_active_ = true; - sink_.start_write({buffer_ + read_idx_, buffer_ + I}, &transfer_handle_, *this); + sink_.start_write({buffer_ + read_idx_, buffer_ + I}, &transfer_handle_, MEMBER_CB(this, on_write_complete)); } else { // nothing to do } } private: - void complete(WriteResult result) final { + void on_write_complete(WriteResult result) { is_active_ = false; transfer_handle_ = 0; @@ -93,7 +93,7 @@ private: * operation at a time but are written to by multiple independent sources. */ template -class AsyncStreamSinkMultiplexer : public AsyncStreamSink, Completer { +class AsyncStreamSinkMultiplexer : public AsyncStreamSink { public: AsyncStreamSinkMultiplexer(AsyncStreamSink& sink) : sink_(sink) {} @@ -102,7 +102,7 @@ public: auto& [slot_in_use, slot_buf, slot_completer] = slots_[i]; if (!__atomic_exchange_n(&slot_in_use, true, __ATOMIC_SEQ_CST)) { slot_buf = buffer; - slot_completer = &completer; + slot_completer = completer; if (handle) { *handle = i + 1; // returning a valid handle of 0 is not a good idea @@ -111,7 +111,7 @@ public: // If the underlying sink wasn't busy, start it now. if (active_slot_ == 0) { active_slot_ = i + 1; - sink_.start_write(slot_buf, &transfer_handle_, *this); + sink_.start_write(slot_buf, &transfer_handle_, MEMBER_CB(this, on_write_complete)); } return; @@ -121,7 +121,7 @@ public: if (handle) { *handle = 0; } - completer.complete({kStreamError, buffer.begin()}); + completer.invoke({kStreamError, buffer.begin()}); } void cancel_write(TransferHandle transfer_handle) final { @@ -134,12 +134,12 @@ public: auto completer = slot_completer; auto end = slot_buf.end(); slot_in_use = false; - safe_complete(completer, {kStreamCancelled, end}); + completer.invoke_and_clear({kStreamCancelled, end}); } } private: - void complete(fibre::WriteResult result) final { + void on_write_complete(fibre::WriteResult result) { transfer_handle_ = 0; auto& [slot_in_use, slot_buf, slot_completer] = slots_[active_slot_ - 1]; @@ -147,7 +147,7 @@ private: auto completer = slot_completer; slot_in_use = false; - safe_complete(completer, result); + completer.invoke_and_clear(result); // Select new slot before announcing completion of the old size_t active_slot = 0; @@ -167,12 +167,12 @@ private: auto& [slot_in_use, slot_buf, slot_completer] = slots_[active_slot - 1]; (void) slot_in_use; (void) slot_completer; - sink_.start_write(slot_buf, &transfer_handle_, *this); + sink_.start_write(slot_buf, &transfer_handle_, MEMBER_CB(this, on_write_complete)); } } AsyncStreamSink& sink_; - std::tuple*> slots_[NSlots]; + std::tuple> slots_[NSlots]; size_t active_slot_ = 0; TransferHandle transfer_handle_ = 0; }; diff --git a/type_info_template.j2 b/type_info_template.j2 index 7e6cda57..7efff78f 100644 --- a/type_info_template.j2 +++ b/type_info_template.j2 @@ -26,7 +26,7 @@ struct [[intf.fullname | to_pascal_case]]TypeInfo : TypeInfo { T* ptr = *(T**)&obj; introspectable_storage_t res; switch (idx) { -[%- for property in intf.attributes.values() %] +[%- for property in intf.get_all_attributes().values() %] case [[loop.index0]]: *(decltype([[intf.c_name]]::get_[[property.name]](std::declval()))*)(&res) = [[intf.c_name]]::get_[[property.name]](ptr); break; [%- endfor %] } @@ -38,7 +38,7 @@ struct [[intf.fullname | to_pascal_case]]TypeInfo : TypeInfo { [% for intf in interfaces.values() %][% if not intf.builtin %] template const PropertyInfo [[intf.fullname | to_pascal_case]]TypeInfo::property_table[] = { -[%- for property in intf.attributes.values() %] +[%- for property in intf.get_all_attributes().values() %] {"[[property.name]]", &[[(property.type.purename or property.type.fullname) | to_pascal_case]]TypeInfo()))>>::singleton}, [%- endfor %] };