]> git.proxmox.com Git - ceph.git/blob - ceph/src/common/async/yield_context.h
import quincy beta 17.1.0
[ceph.git] / ceph / src / common / async / yield_context.h
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3 /*
4 * Ceph - scalable distributed file system
5 *
6 * Copyright (C) 2018 Red Hat, Inc
7 *
8 * This is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License version 2.1, as published by the Free Software
11 * Foundation. See file COPYING.
12 *
13 */
14
15 #pragma once
16
17 #include <boost/range/begin.hpp>
18 #include <boost/range/end.hpp>
19 #include <boost/asio/io_context.hpp>
20
21 #include "acconfig.h"
22
23 #include <spawn/spawn.hpp>
24
25 // use explicit executor types instead of the type-erased boost::asio::executor.
26 // coroutines wrap the default io_context executor with a strand executor
27 using yield_context = spawn::basic_yield_context<
28 boost::asio::executor_binder<void(*)(),
29 boost::asio::strand<boost::asio::io_context::executor_type>>>;
30
31 /// optional-like wrapper for a spawn::yield_context and its associated
32 /// boost::asio::io_context. operations that take an optional_yield argument
33 /// will, when passed a non-empty yield context, suspend this coroutine instead
34 /// of the blocking the thread of execution
35 class optional_yield {
36 boost::asio::io_context *c = nullptr;
37 yield_context *y = nullptr;
38 public:
39 /// construct with a valid io and yield_context
40 explicit optional_yield(boost::asio::io_context& c,
41 yield_context& y) noexcept
42 : c(&c), y(&y) {}
43
44 /// type tag to construct an empty object
45 struct empty_t {};
46 optional_yield(empty_t) noexcept {}
47
48 /// implicit conversion to bool, returns true if non-empty
49 operator bool() const noexcept { return y; }
50
51 /// return a reference to the associated io_context. only valid if non-empty
52 boost::asio::io_context& get_io_context() const noexcept { return *c; }
53
54 /// return a reference to the yield_context. only valid if non-empty
55 yield_context& get_yield_context() const noexcept { return *y; }
56 };
57
58 // type tag object to construct an empty optional_yield
59 static constexpr optional_yield::empty_t null_yield{};