diff options
Diffstat (limited to 'src/libutil/serialise.cc')
-rw-r--r-- | src/libutil/serialise.cc | 171 |
1 files changed, 0 insertions, 171 deletions
diff --git a/src/libutil/serialise.cc b/src/libutil/serialise.cc index 11bc183cc..a294a7ea1 100644 --- a/src/libutil/serialise.cc +++ b/src/libutil/serialise.cc @@ -149,177 +149,6 @@ size_t StringSource::read(char * data, size_t len) } -#if BOOST_VERSION >= 106300 && BOOST_VERSION < 106600 -#error Coroutines are broken in this version of Boost! -#endif - -/* A concrete datatype allow virtual dispatch of stack allocation methods. */ -struct VirtualStackAllocator { - StackAllocator *allocator = StackAllocator::defaultAllocator; - - boost::context::stack_context allocate() { - return allocator->allocate(); - } - - void deallocate(boost::context::stack_context sctx) { - allocator->deallocate(sctx); - } -}; - - -/* This class reifies the default boost coroutine stack allocation strategy with - a virtual interface. */ -class DefaultStackAllocator : public StackAllocator { - boost::coroutines2::default_stack stack; - - boost::context::stack_context allocate() { - return stack.allocate(); - } - - void deallocate(boost::context::stack_context sctx) { - stack.deallocate(sctx); - } -}; - -static DefaultStackAllocator defaultAllocatorSingleton; - -StackAllocator *StackAllocator::defaultAllocator = &defaultAllocatorSingleton; - - -std::shared_ptr<void> (*create_coro_gc_hook)() = []() -> std::shared_ptr<void> { - return {}; -}; - -/* This class is used for entry and exit hooks on coroutines */ -class CoroutineContext { - /* Disable GC when entering the coroutine without the boehm patch, - * since it doesn't find the main thread stack in this case. - * std::shared_ptr<void> performs type-erasure, so it will call the right - * deleter. */ - const std::shared_ptr<void> coro_gc_hook = create_coro_gc_hook(); -public: - CoroutineContext() {}; - ~CoroutineContext() {}; -}; - -std::unique_ptr<FinishSink> sourceToSink(std::function<void(Source &)> fun) -{ - struct SourceToSink : FinishSink - { - typedef boost::coroutines2::coroutine<bool> coro_t; - - std::function<void(Source &)> fun; - std::optional<coro_t::push_type> coro; - - SourceToSink(std::function<void(Source &)> fun) : fun(fun) - { - } - - std::string_view cur; - - void operator () (std::string_view in) override - { - if (in.empty()) return; - cur = in; - - if (!coro) { - CoroutineContext ctx; - coro = coro_t::push_type(VirtualStackAllocator{}, [&](coro_t::pull_type & yield) { - LambdaSource source([&](char *out, size_t out_len) { - if (cur.empty()) { - yield(); - if (yield.get()) { - throw EndOfFile("coroutine exhausted"); - } - } - - size_t n = std::min(cur.size(), out_len); - memcpy(out, cur.data(), n); - cur.remove_prefix(n); - return n; - }); - fun(source); - }); - } - - if (!*coro) { abort(); } - - if (!cur.empty()) { - CoroutineContext ctx; - (*coro)(false); - } - } - - void finish() override - { - if (!coro) return; - if (!*coro) abort(); - { - CoroutineContext ctx; - (*coro)(true); - } - if (*coro) abort(); - } - }; - - return std::make_unique<SourceToSink>(fun); -} - - -std::unique_ptr<Source> sinkToSource(std::function<void(Sink &)> fun) -{ - struct SinkToSource : Source - { - typedef boost::coroutines2::coroutine<std::string> coro_t; - - std::function<void(Sink &)> fun; - std::optional<coro_t::pull_type> coro; - - SinkToSource(std::function<void(Sink &)> fun) - : fun(fun) - { - } - - std::string cur; - size_t pos = 0; - - size_t read(char * data, size_t len) override - { - if (!coro) { - CoroutineContext ctx; - coro = coro_t::pull_type(VirtualStackAllocator{}, [&](coro_t::push_type & yield) { - LambdaSink sink([&](std::string_view data) { - if (!data.empty()) yield(std::string(data)); - }); - fun(sink); - }); - } - - if (!*coro) { - throw EndOfFile("coroutine has finished"); - } - - if (pos == cur.size()) { - if (!cur.empty()) { - CoroutineContext ctx; - (*coro)(); - } - cur = coro->get(); - pos = 0; - } - - auto n = std::min(cur.size() - pos, len); - memcpy(data, cur.data() + pos, n); - pos += n; - - return n; - } - }; - - return std::make_unique<SinkToSource>(fun); -} - - void writePadding(size_t len, Sink & sink) { if (len % 8) { |