async: remove tag_invoke calls
P2300R9 removed usage of tag_invoke. stdexec still has it
but in order to be forward compliant with the C++26 standard
we should modernize the code and remove its usage. This also
has the benefit of simplifying most sender/receiver implementations.
Signed-off-by: Patrick Williams <patrick@stwcx.xyz>
Change-Id: Ib0a1d0a82485c8d247a18daa020d0bba2249e95c
diff --git a/include/sdbusplus/async/callback.hpp b/include/sdbusplus/async/callback.hpp
index 0cdf6a1..10db758 100644
--- a/include/sdbusplus/async/callback.hpp
+++ b/include/sdbusplus/async/callback.hpp
@@ -100,12 +100,11 @@
}
// Call the init function upon Sender start.
- friend void tag_invoke(execution::start_t,
- callback_operation& self) noexcept
+ void start() noexcept
{
try
{
- auto rc = self.init(handler, &self);
+ auto rc = init(handler, this);
if (rc < 0)
{
throw exception::SdBusError(-rc, __PRETTY_FUNCTION__);
@@ -113,8 +112,7 @@
}
catch (...)
{
- execution::set_error(std::move(self.receiver),
- std::current_exception());
+ execution::set_error(std::move(receiver), std::current_exception());
}
}
@@ -132,21 +130,20 @@
template <takes_msg_handler Init>
struct callback_sender
{
- using is_sender = void;
+ using sender_concept = execution::sender_t;
explicit callback_sender(Init init) : init(std::move(init)) {};
// This Sender yields a message_t.
- friend auto tag_invoke(execution::get_completion_signatures_t,
- const callback_sender&, auto)
+ template <typename Self, class... Env>
+ static constexpr auto get_completion_signatures(Self&&, Env&&...)
-> execution::completion_signatures<execution::set_value_t(message_t),
execution::set_stopped_t()>;
template <execution::receiver R>
- friend auto tag_invoke(execution::connect_t, callback_sender&& self, R r)
- -> callback_operation<Init, R>
+ auto connect(R r) -> callback_operation<Init, R>
{
- return {std::move(self.init), std::move(r)};
+ return {std::move(init), std::move(r)};
}
private:
diff --git a/include/sdbusplus/async/fdio.hpp b/include/sdbusplus/async/fdio.hpp
index abf3b42..de98cad 100644
--- a/include/sdbusplus/async/fdio.hpp
+++ b/include/sdbusplus/async/fdio.hpp
@@ -70,16 +70,12 @@
friend fdio;
- friend void tag_invoke(execution::start_t, fdio_completion& self) noexcept
- {
- self.arm();
- }
+ void start() noexcept;
private:
virtual void complete() noexcept = 0;
virtual void error(std::exception_ptr exceptionPtr) noexcept = 0;
virtual void stop() noexcept = 0;
- void arm() noexcept;
fdio& fdioInstance;
event_source_t source;
@@ -115,24 +111,23 @@
// fdio Sender implementation.
struct fdio_sender
{
- using is_sender = void;
+ using sender_concept = execution::sender_t;
fdio_sender() = delete;
explicit fdio_sender(fdio& fdioInstance) noexcept :
fdioInstance(fdioInstance) {};
- friend auto tag_invoke(execution::get_completion_signatures_t,
- const fdio_sender&, auto)
+ template <typename Self, class... Env>
+ static constexpr auto get_completion_signatures(Self&&, Env&&...)
-> execution::completion_signatures<
execution::set_value_t(),
execution::set_error_t(std::exception_ptr),
execution::set_stopped_t()>;
template <execution::receiver R>
- friend auto tag_invoke(execution::connect_t, fdio_sender&& self, R r)
- -> fdio_operation<R>
+ auto connect(R r) -> fdio_operation<R>
{
- return {self.fdioInstance, std::move(r)};
+ return {fdioInstance, std::move(r)};
}
private:
diff --git a/include/sdbusplus/async/match.hpp b/include/sdbusplus/async/match.hpp
index 4dbc61a..86a0dbc 100644
--- a/include/sdbusplus/async/match.hpp
+++ b/include/sdbusplus/async/match.hpp
@@ -86,15 +86,11 @@
friend match;
- friend void tag_invoke(execution::start_t, match_completion& self) noexcept
- {
- self.arm();
- }
+ void start() noexcept;
private:
virtual void complete(message_t&&) noexcept = 0;
virtual void stop() noexcept = 0;
- void arm() noexcept;
match& m;
};
@@ -124,21 +120,20 @@
// match Sender implementation.
struct match_sender
{
- using is_sender = void;
+ using sender_concept = execution::sender_t;
match_sender() = delete;
explicit match_sender(match& m) noexcept : m(m) {};
- friend auto tag_invoke(execution::get_completion_signatures_t,
- const match_sender&, auto)
+ template <typename Self, class... Env>
+ static constexpr auto get_completion_signatures(Self&&, Env&&...)
-> execution::completion_signatures<execution::set_value_t(message_t),
execution::set_stopped_t()>;
template <execution::receiver R>
- friend auto tag_invoke(execution::connect_t, match_sender&& self, R r)
- -> match_operation<R>
+ auto connect(R r) -> match_operation<R>
{
- return {self.m, std::move(r)};
+ return {m, std::move(r)};
}
private:
diff --git a/include/sdbusplus/async/mutex.hpp b/include/sdbusplus/async/mutex.hpp
index d937f92..db13882 100644
--- a/include/sdbusplus/async/mutex.hpp
+++ b/include/sdbusplus/async/mutex.hpp
@@ -85,15 +85,11 @@
friend mutex;
- friend void tag_invoke(execution::start_t, mutex_completion& self) noexcept
- {
- self.arm();
- }
+ void start() noexcept;
private:
virtual void complete() noexcept = 0;
virtual void stop() noexcept = 0;
- void arm() noexcept;
mutex& mutexInstance;
};
@@ -123,22 +119,21 @@
// mutex sender
struct mutex_sender
{
- using is_sender = void;
+ using sender_concept = execution::sender_t;
mutex_sender() = delete;
explicit mutex_sender(mutex& mutexInstance) noexcept :
mutexInstance(mutexInstance) {};
- friend auto tag_invoke(execution::get_completion_signatures_t,
- const mutex_sender&, auto)
+ template <typename Self, class... Env>
+ static constexpr auto get_completion_signatures(Self&&, Env&&...)
-> execution::completion_signatures<execution::set_value_t(),
execution::set_stopped_t()>;
template <execution::receiver R>
- friend auto tag_invoke(execution::connect_t, mutex_sender&& self, R r)
- -> mutex_operation<R>
+ auto connect(R r) -> mutex_operation<R>
{
- return {self.mutexInstance, std::move(r)};
+ return {mutexInstance, std::move(r)};
}
private:
diff --git a/include/sdbusplus/async/timer.hpp b/include/sdbusplus/async/timer.hpp
index 582d248..808c8fe 100644
--- a/include/sdbusplus/async/timer.hpp
+++ b/include/sdbusplus/async/timer.hpp
@@ -46,17 +46,15 @@
return 0;
}
- friend auto tag_invoke(execution::start_t, sleep_operation& self) noexcept
+ void start() noexcept
{
try
{
- self.source =
- self.event_loop().add_oneshot_timer(handler, &self, self.time);
+ source = event_loop().add_oneshot_timer(handler, this, time);
}
catch (...)
{
- execution::set_error(std::move(self.receiver),
- std::current_exception());
+ execution::set_error(std::move(receiver), std::current_exception());
}
}
@@ -77,7 +75,7 @@
*/
struct sleep_sender : public context_ref, details::context_friend
{
- using is_sender = void;
+ using sender_concept = execution::sender_t;
sleep_sender() = delete;
@@ -85,18 +83,17 @@
context_ref(ctx), time(time)
{}
- friend auto tag_invoke(execution::get_completion_signatures_t,
- const sleep_sender&, auto)
+ template <typename Self, class... Env>
+ static constexpr auto get_completion_signatures(Self&&, Env&&...)
-> execution::completion_signatures<
execution::set_value_t(),
execution::set_error_t(std::exception_ptr),
execution::set_stopped_t()>;
template <execution::receiver R>
- friend auto tag_invoke(execution::connect_t, sleep_sender&& self, R r)
- -> sleep_operation<R>
+ auto connect(R r) -> sleep_operation<R>
{
- return {self.ctx, self.time, std::move(r)};
+ return {ctx, time, std::move(r)};
}
static auto sleep_for(context& ctx, event_t::time_resolution time)
diff --git a/src/async/context.cpp b/src/async/context.cpp
index d4ec5e9..0b31391 100644
--- a/src/async/context.cpp
+++ b/src/async/context.cpp
@@ -34,8 +34,7 @@
// Called by the `caller` to indicate the Sender should be stopped.
virtual void stop() noexcept = 0;
- // Arm the completion event.
- void arm() noexcept;
+ void start() noexcept;
// Data to share with the worker.
event_t::time_resolution timeout{};
@@ -70,32 +69,25 @@
execution::set_value(std::move(this->receiver));
}
- friend void tag_invoke(execution::start_t,
- wait_process_operation& self) noexcept
- {
- self.arm();
- }
-
R receiver;
};
/* The sender for the wait/process event. */
struct wait_process_sender : public context_ref
{
- using is_sender = void;
+ using sender_concept = execution::sender_t;
explicit wait_process_sender(context& ctx) : context_ref(ctx) {}
- friend auto tag_invoke(execution::get_completion_signatures_t,
- const wait_process_sender&, auto)
+ template <typename Self, class... Env>
+ static constexpr auto get_completion_signatures(Self&&, Env&&...)
-> execution::completion_signatures<execution::set_value_t()>;
template <execution::receiver R>
- friend auto tag_invoke(execution::connect_t, wait_process_sender&& self,
- R r) -> wait_process_operation<R>
+ auto connect(R r) -> wait_process_operation<R>
{
// Create the completion for the wait.
- return {self.ctx, std::move(r)};
+ return {ctx, std::move(r)};
}
};
@@ -282,7 +274,7 @@
}
}
-void details::wait_process_completion::arm() noexcept
+void details::wait_process_completion::start() noexcept
{
// Call process. True indicates something was handled and we do not
// need to `wait`, because there might be yet another pending operation
diff --git a/src/async/fdio.cpp b/src/async/fdio.cpp
index 94c79d1..df54cf0 100644
--- a/src/async/fdio.cpp
+++ b/src/async/fdio.cpp
@@ -59,7 +59,7 @@
}
}
-void fdio_completion::arm() noexcept
+void fdio_completion::start() noexcept
{
// Set ourselves as the awaiting Receiver
std::unique_lock l{fdioInstance.lock};
diff --git a/src/async/match.cpp b/src/async/match.cpp
index bedce38..7d05ba6 100644
--- a/src/async/match.cpp
+++ b/src/async/match.cpp
@@ -42,7 +42,7 @@
}
}
-void match_ns::match_completion::arm() noexcept
+void match_ns::match_completion::start() noexcept
{
// Set ourselves as the awaiting Receiver and see if there is a message
// to immediately complete on.
diff --git a/src/async/mutex.cpp b/src/async/mutex.cpp
index 44694c6..19e5d3c 100644
--- a/src/async/mutex.cpp
+++ b/src/async/mutex.cpp
@@ -34,7 +34,7 @@
namespace mutex_ns
{
-void mutex_completion::arm() noexcept
+void mutex_completion::start() noexcept
{
std::unique_lock l{mutexInstance.lock};