Seastar
High performance C++ framework for concurrent servers
poll.hh
1 /*
2  * This file is open source software, licensed to you under the terms
3  * of the Apache License, Version 2.0 (the "License"). See the NOTICE file
4  * distributed with this work for additional information regarding copyright
5  * ownership. You may not use this file except in compliance with the License.
6  *
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing,
12  * software distributed under the License is distributed on an
13  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14  * KIND, either express or implied. See the License for the
15  * specific language governing permissions and limitations
16  * under the License.
17  */
18 /*
19  * Copyright 2019 ScyllaDB
20  */
21 
22 #pragma once
23 
24 namespace seastar {
25 
26 struct pollfn {
27  virtual ~pollfn() {}
28  // Returns true if work was done (false = idle)
29  virtual bool poll() = 0;
30  // Checks if work needs to be done, but without actually doing any
31  // returns true if works needs to be done (false = idle)
32  virtual bool pure_poll() = 0;
33  // Tries to enter interrupt mode.
34  //
35  // If it returns true, then events from this poller will wake
36  // a sleeping idle loop, and exit_interrupt_mode() must be called
37  // to return to normal polling.
38  //
39  // If it returns false, the sleeping idle loop may not be entered.
40  virtual bool try_enter_interrupt_mode() = 0;
41  virtual void exit_interrupt_mode() = 0;
42 };
43 
44 // The common case for poller -- do not make any difference between
45 // poll() and pure_poll(), always/never agree to go to sleep and do
46 // nothing on wakeup.
47 template <bool Passive>
48 struct simple_pollfn : public pollfn {
49  virtual bool pure_poll() override final {
50  return poll();
51  }
52  virtual bool try_enter_interrupt_mode() override final {
53  return Passive;
54  }
55  virtual void exit_interrupt_mode() override final {
56  }
57 };
58 
59 namespace internal {
60 
61 template <typename Func>
62 SEASTAR_CONCEPT( requires std::is_invocable_r_v<bool, Func> )
63 inline
64 std::unique_ptr<seastar::pollfn> make_pollfn(Func&& func) {
65  struct the_pollfn : simple_pollfn<false> {
66  the_pollfn(Func&& func) : func(std::forward<Func>(func)) {}
67  Func func;
68  virtual bool poll() override final {
69  return func();
70  }
71  };
72  return std::make_unique<the_pollfn>(std::forward<Func>(func));
73 }
74 
75 class poller {
76  std::unique_ptr<pollfn> _pollfn;
77  class registration_task;
78  class deregistration_task;
79  registration_task* _registration_task = nullptr;
80 public:
81  template <typename Func>
82  SEASTAR_CONCEPT( requires std::is_invocable_r_v<bool, Func> )
83  static poller simple(Func&& poll) {
84  return poller(make_pollfn(std::forward<Func>(poll)));
85  }
86  poller(std::unique_ptr<pollfn> fn)
87  : _pollfn(std::move(fn)) {
88  do_register();
89  }
90  ~poller();
91  poller(poller&& x) noexcept;
92  poller& operator=(poller&& x) noexcept;
93  void do_register() noexcept;
94  friend class reactor;
95 };
96 
97 } // internal namespace
98 
99 }
Seastar API namespace.
Definition: abort_on_ebadf.hh:26
Definition: poll.hh:26
Definition: poll.hh:48