async: add scope

In order to be able to create multiple subtasks as a collection
and in order to make sure we keep good track of any tasks that
are created by the context, add a `scope` as a container of subtasks.
This is partially modelled after the C++ P2519 proposal.

Signed-off-by: Patrick Williams <patrick@stwcx.xyz>
Change-Id: I6e99b2fa2829d80c320491991f7e038f122963a9
diff --git a/src/async/context.cpp b/src/async/context.cpp
index 007a266..38d3a89 100644
--- a/src/async/context.cpp
+++ b/src/async/context.cpp
@@ -164,10 +164,10 @@
     // This shouldn't start detached because we want to be able to forward
     // failures back to the 'run'.  execution::ensure_started isn't
     // implemented yet, so we don't have a lot of other options.
-    execution::start_detached(std::move(startup));
+    spawn(std::move(startup));
 
     // Also start up the sdbus 'wait/process' loop.
-    execution::start_detached(details::wait_process_completion::loop(*this));
+    spawn(details::wait_process_completion::loop(*this));
 
     // Run the execution::run_loop to handle all the tasks.
     loop.run();
diff --git a/src/async/scope.cpp b/src/async/scope.cpp
new file mode 100644
index 0000000..efdc5f6
--- /dev/null
+++ b/src/async/scope.cpp
@@ -0,0 +1,26 @@
+#include <sdbusplus/async/scope.hpp>
+
+#include <exception>
+
+namespace sdbusplus::async
+{
+scope::~scope() noexcept(false)
+{
+    if (count != 0)
+    {
+        throw std::logic_error(
+            "sdbusplus::async::scope destructed while tasks are pending.");
+    }
+}
+
+void scope::started_task() noexcept
+{
+    ++count;
+}
+
+void scope::ended_task() noexcept
+{
+    --count;
+}
+
+} // namespace sdbusplus::async