[sessionmgr] Properly employ deferred_action.

deferred_action is meant to defer an action until the end of some
scope, but we use it merely to defer it to some time later, but
decidedly not to the time of destruction, at which time it must
not execute at all if it hasn't yet.

So we use a simple fit::function<> instead that we simply protect
against double invocation using a mutable bool flag on the capture
list. This is especially simple because the capture list already
is mutable.

Amends https://fuchsia-review.googlesource.com/c/peridot/+/240436

TESTED=/pkgfs/packages/modular_tests/0/test/run_modular_tests.sh

Change-Id: I8851a349bbd4c55312fc59c443f74f98145bd2ea
diff --git a/bin/sessionmgr/sessionmgr_impl.cc b/bin/sessionmgr/sessionmgr_impl.cc
index ad00f1b..5abe13c 100644
--- a/bin/sessionmgr/sessionmgr_impl.cc
+++ b/bin/sessionmgr/sessionmgr_impl.cc
@@ -195,10 +195,15 @@
   // shell (see how RunSessionShell() initializes session_shell_services_) to
   // lazily initialize the following services only once they are requested
   // for the first time.
-  finish_initialization_ = fit::defer<fit::closure>(
-      [this, session_shell_url = session_shell.url,
+  finish_initialization_ =
+      [this, called = false, session_shell_url = session_shell.url,
        ledger_token_manager = std::move(ledger_token_manager),
        story_shell = std::move(story_shell)]() mutable {
+        if (called) {
+          return;
+        }
+        called = true;
+
         InitializeLedger(std::move(ledger_token_manager));
         InitializeDeviceMap();
         InitializeMessageQueueManager();
@@ -209,7 +214,7 @@
         });
         InitializeClipboard();
         ReportEvent(ModularEvent::BOOTED_TO_SESSIONMGR);
-      });
+      };
 
   InitializeUser(std::move(account), std::move(agent_token_manager),
                  std::move(user_context));
@@ -703,7 +708,7 @@
         if (terminating_) {
           return;
         }
-        finish_initialization_.call();
+        finish_initialization_();
         session_shell_context_bindings_.AddBinding(this, std::move(request));
       });
 
@@ -713,7 +718,7 @@
         if (terminating_) {
           return;
         }
-        finish_initialization_.call();
+        finish_initialization_();
         session_shell_component_context_impl_->Connect(std::move(request));
       });
 
@@ -723,7 +728,7 @@
         if (terminating_) {
           return;
         }
-        finish_initialization_.call();
+        finish_initialization_();
         puppet_master_impl_->Connect(std::move(request));
       });
 
@@ -733,7 +738,7 @@
         if (terminating_) {
           return;
         }
-        finish_initialization_.call();
+        finish_initialization_();
         fuchsia::modular::ComponentScope component_scope;
         component_scope.set_global_scope(fuchsia::modular::GlobalScope());
         user_intelligence_provider_impl_->GetComponentIntelligenceServices(
diff --git a/bin/sessionmgr/sessionmgr_impl.h b/bin/sessionmgr/sessionmgr_impl.h
index 5cca15c..19cc922 100644
--- a/bin/sessionmgr/sessionmgr_impl.h
+++ b/bin/sessionmgr/sessionmgr_impl.h
@@ -21,7 +21,7 @@
 #include <lib/component/cpp/service_provider_impl.h>
 #include <lib/fidl/cpp/binding.h>
 #include <lib/fidl/cpp/interface_ptr.h>
-#include <lib/fit/defer.h>
+#include <lib/fit/function.h>
 #include <lib/fxl/macros.h>
 #include <zx/eventpair.h>
 
@@ -305,7 +305,10 @@
 
   OperationQueue operation_queue_;
 
-  fit::deferred_action<fit::closure> finish_initialization_;
+  // Part of Initialize() that is deferred until the first environment service
+  // request is received from the session shell, in order to accelerate the
+  // startup of session shell.
+  fit::function<void()> finish_initialization_{[]{}};
 
   // Set to |true| when sessionmgr starts its terminating sequence;  this flag
   // can be used to determine whether to reject vending FIDL services.