warden.poll.hpp

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#pragma once


#include <felspar/io/warden.hpp>

#include <map>
#include <vector>


namespace felspar::io {


    class poll_warden : public warden {
        struct retrier;
        template<typename R>
        struct completion;
        struct request {
            std::vector<retrier *> reads, writes;
        };
        std::map<socket_descriptor, request> requests;
        std::multimap<std::chrono::steady_clock::time_point, retrier *> timeouts;

        void run_until(felspar::coro::coroutine_handle<>) override;

        struct close_completion;
        struct sleep_completion;
        struct read_some_completion;
        struct write_some_completion;
        struct accept_completion;
        struct connect_completion;
        struct read_ready_completion;
        struct write_ready_completion;

      public:
        poll_warden();
        ~poll_warden();

        void run_batch() override;

      protected:

File descriptors

42
43
44
        iop<void> do_close(
                socket_descriptor fd,
                felspar::source_location const &) override;

Time management

47
48
49
        iop<void> do_sleep(
                std::chrono::nanoseconds,
                felspar::source_location const &) override;

Read & write

52
53
54
55
56
57
58
59
60
61
        iop<std::size_t> do_read_some(
                socket_descriptor fd,
                std::span<std::byte>,
                std::optional<std::chrono::nanoseconds>,
                felspar::source_location const &) override;
        iop<std::size_t> do_write_some(
                socket_descriptor fd,
                std::span<std::byte const>,
                std::optional<std::chrono::nanoseconds> timeout,
                felspar::source_location const &) override;

Sockets

64
65
66
67
68
69
70
71
72
73
74
75
76
        void do_prepare_socket(
                socket_descriptor sock,
                felspar::source_location const &) override;
        iop<socket_descriptor> do_accept(
                socket_descriptor fd,
                std::optional<std::chrono::nanoseconds> timeout,
                felspar::source_location const &) override;
        iop<void> do_connect(
                socket_descriptor fd,
                sockaddr const *,
                socklen_t,
                std::optional<std::chrono::nanoseconds> timeout,
                felspar::source_location const &) override;

File descriptor readiness

79
80
81
82
83
84
85
86
87
88
        iop<void> do_read_ready(
                socket_descriptor fd,
                std::optional<std::chrono::nanoseconds> timeout,
                felspar::source_location const &) override;
        iop<void> do_write_ready(
                socket_descriptor fd,
                std::optional<std::chrono::nanoseconds> timeout,
                felspar::source_location const &) override;

      private:

Used for managing the poll loop

90
91
        struct loop_data;
        std::unique_ptr<loop_data> bookkeeping;

Resume any coros that have now timed out and return the time out number to pass to poll

95
        int clear_timeouts();

Put together data for poll call and then process resulting revents

 97
 98
 99
100
101
        void do_poll(int timeout);
    };


}