[login_manager] Fix thread-safety issues at shutdown

I was persisting the signed settings store to disk from the main thread at shutdown.
In general, this work is only supposed to be done from the background thread.
In practice, this was probably fine.  In unit tests, it was possible that I could call
store_->Persist() on one thread while I was already doing it on another thread.  Boo me!

BUG=12505
STATUS=Fixed
TEST=unit tests

Change-Id: I3d9b9639645712bc248f8e4be5336d16abce0295

Review URL: http://codereview.chromium.org/6604012
diff --git a/session_manager_service.cc b/session_manager_service.cc
index d708ef1..29313f3 100644
--- a/session_manager_service.cc
+++ b/session_manager_service.cc
@@ -328,7 +328,12 @@
   }
 
   // Even if we haven't gotten around to processing a persist task.
-  store_->Persist();
+  base::WaitableEvent event(true, false);
+  io_thread_.message_loop()->PostTask(
+      FROM_HERE, NewRunnableMethod(this,
+                                   &SessionManagerService::PersistStoreSync,
+                                   &event));
+  event.Wait();
   io_thread_.Stop();
   message_loop_->PostTask(FROM_HERE, new MessageLoop::QuitTask());
   LOG(INFO) << "SessionManagerService quitting run loop";
@@ -909,6 +914,12 @@
                                    what_happened));
 }
 
+void SessionManagerService::PersistStoreSync(base::WaitableEvent* event) {
+  store_->Persist();
+  LOG(INFO) << "Persisted Store to disk.";
+  event->Signal();
+}
+
 void SessionManagerService::PersistStore() {
   LOG(INFO) << "Persisting Store to disk.";
   bool what_happened = store_->Persist();
diff --git a/session_manager_service.h b/session_manager_service.h
index 86a5615..ce59c91 100644
--- a/session_manager_service.h
+++ b/session_manager_service.h
@@ -19,6 +19,7 @@
 #include <base/ref_counted.h>
 #include <base/scoped_ptr.h>
 #include <base/thread.h>
+#include <base/waitable_event.h>
 #include <chromeos/dbus/abstract_dbus_service.h>
 #include <chromeos/dbus/dbus.h>
 #include <chromeos/dbus/service_constants.h>
@@ -55,27 +56,6 @@
     : public base::RefCountedThreadSafe<SessionManagerService>,
       public chromeos::dbus::AbstractDbusService {
  public:
-  struct PersistKeyData {
-   public:
-    PersistKeyData(SystemUtils* utils, OwnerKey* key)
-        : signaler(utils),
-          to_persist(key) {
-    }
-    ~PersistKeyData() {}
-    SystemUtils* signaler;
-    OwnerKey* to_persist;
-  };
-
-  struct PersistStoreData {
-   public:
-    PersistStoreData(SystemUtils* utils, PrefStore* store)
-        : signaler(utils),
-          to_persist(store) {
-    }
-    ~PersistStoreData() {}
-    SystemUtils* signaler;
-    PrefStore* to_persist;
-  };
 
   SessionManagerService(std::vector<ChildJobInterface*> child_jobs);
   virtual ~SessionManagerService();
@@ -471,6 +451,10 @@
   // to signal Chromium when done.
   void PersistStore();
 
+  // |store_| is persisted to disk, and |event| is signaled when done.  This
+  // is used to provide synchronous, threadsafe persisting.
+  void PersistStoreSync(base::WaitableEvent* event);
+
   void StartKeyGeneration();
 
   // Uses |system_| to send |signal_name| to Chromium.  Attaches a payload