transaction: avoid recursive sdbus calls

The server bindings for transactions use the bus unique_name
to create a transaction ID.  If the bus object is not in RUNNING
state, the unique_name call causes, deep in sd-bus, a call
into sd_bus_process to get the bus up and running since the unique_name
is assigned by the dbus-daemon.

When DBus objects are created there is a call to generate a signal
for object/interface creation.  In sd-bus this creates a message and
calls back into the server bindings to read all of the properties of
the interface.  When the transaction ID is assigned, calling
unique_name, this causes a recursive entry into sd_bus_process which
asserts.

The ideal solution would be to catch all C++ objects that might result
in a recursive call like this and call unique_name before.  This would
currently be on slot, server/match, and server/interface and may be
others in the future.  Instead, I took a simple approach, which is
to get the unique_name immediately after instantiating any bus-object.

Fixes openbmc/openbmc#1072.

Change-Id: I024fd2f46fd08c85317e102dfced88a11e18f9de
Signed-off-by: Patrick Williams <patrick@stwcx.xyz>
diff --git a/sdbusplus/bus.hpp b/sdbusplus/bus.hpp
index 6365644..48c8791 100644
--- a/sdbusplus/bus.hpp
+++ b/sdbusplus/bus.hpp
@@ -69,7 +69,7 @@
      *
      *  Takes ownership of the bus-pointer and releases it when done.
      */
-    explicit bus(busp_t b) : _bus(b) {}
+    explicit bus(busp_t b);
 
     /** @brief Release ownership of the stored bus-pointer. */
     busp_t release() { return _bus.release(); }
@@ -237,6 +237,22 @@
         details::bus _bus;
 };
 
+inline bus::bus(busp_t b) : _bus(b)
+{
+#ifndef DISABLE_TRANSACTION
+    // Emitting object added causes a message to get the properties
+    // which can trigger a 'transaction' in the server bindings.  If
+    // the bus isn't up far enough, this causes an assert deep in
+    // sd-bus code.  Get the 'unique_name' to ensure the bus is up far
+    // enough to avoid the assert.
+    if (b != nullptr)
+    {
+        get_unique_name();
+    }
+#endif
+}
+
+
 inline bus new_default()
 {
     sd_bus* b = nullptr;