buffet: Make ExportedPropertySet threadsafe
In Chrome, we have both a DBus thread and some main thread (an 'origin'
thread). Objects related to DBus functionality need to accomodate this
so that we can send this upstream. This mostly just means that we need
to add assertions that developers are using the API correctly, so that
the use of weak pointers is safe.
BUG=chromium:360831
TEST=Unittests pass. buffet_BasicDBusAPI still passes.
Change-Id: Ibb48a5e65c7cb02e5edce9cbf85432bed70d7686
Reviewed-on: https://chromium-review.googlesource.com/193505
Reviewed-by: Alex Vakulenko <avakulenko@chromium.org>
Tested-by: Christopher Wiley <wiley@chromium.org>
Commit-Queue: Alex Vakulenko <avakulenko@chromium.org>
diff --git a/buffet/main.cc b/buffet/main.cc
index 37a9031..6d8ddc2 100644
--- a/buffet/main.cc
+++ b/buffet/main.cc
@@ -14,9 +14,12 @@
#include <base/strings/stringprintf.h>
#include <sysexits.h>
+#include "buffet/async_event_sequencer.h"
#include "buffet/dbus_manager.h"
#include "buffet/manager.h"
+using buffet::dbus_utils::AsyncEventSequencer;
+
namespace {
static const char kLogRoot[] = "logroot";
@@ -72,6 +75,31 @@
logging::InitLogging(settings);
}
+void TakeServiceOwnership(scoped_refptr<dbus::Bus> bus, bool success) {
+ // Success should always be true since we've said that failures are
+ // fatal.
+ CHECK(success) << "Init of one or more objects has failed.";
+ CHECK(bus->RequestOwnershipAndBlock(buffet::dbus_constants::kServiceName,
+ dbus::Bus::REQUIRE_PRIMARY))
+ << "Unable to take ownership of " << buffet::dbus_constants::kServiceName;
+}
+
+void EnterMainLoop(base::MessageLoopForIO* message_loop,
+ scoped_refptr<dbus::Bus> bus) {
+ scoped_refptr<AsyncEventSequencer> sequencer(new AsyncEventSequencer());
+ buffet::DBusManager dbus_manager(bus.get());
+ dbus_manager.Init(sequencer->GetHandler("DBusManager.Init() failed.", true));
+ buffet::Manager manager(bus.get());
+ manager.Init(sequencer->GetHandler("Manager.Init() failed.", true));
+ sequencer->OnAllTasksCompletedCall(
+ {base::Bind(&TakeServiceOwnership, bus)});
+ // Release our handle on the sequencer so that it gets deleted after
+ // both callbacks return.
+ sequencer = nullptr;
+ LOG(INFO) << "Entering mainloop.";
+ message_loop->Run();
+}
+
} // namespace
int main(int argc, char* argv[]) {
@@ -94,15 +122,15 @@
base::AtExitManager at_exit_manager;
base::MessageLoopForIO message_loop;
- // Initialize the dbus_manager.
- buffet::DBusManager dbus_manager;
- dbus_manager.Init();
- {
- // The Manager needs the dbus_manager to remain in scope for its lifetime.
- buffet::Manager manager(&dbus_manager);
- message_loop.Run();
- }
+ dbus::Bus::Options options;
+ // TODO(sosa): Should this be on the system bus?
+ options.bus_type = dbus::Bus::SYSTEM;
+ scoped_refptr<dbus::Bus> bus(new dbus::Bus(options));
+ CHECK(bus->Connect());
+ // Our top level objects expect the bus to exist in a connected state for
+ // the duration of their lifetimes.
+ EnterMainLoop(&message_loop, bus);
+ bus->ShutdownAndBlock();
- dbus_manager.Finalize();
return EX_OK;
}