[login_manager] Be more aggressive about de-registering child-exit handlers

Perhaps doing this earlier in the shutdown process will make 14840 go away.  Either way, there still exists something of a race here.  Try to close it.

(port of http://gerrit.chromium.org/gerrit/1074 to the R12 branch)

BUG=chromium-os:14840
TEST=unit tests, suite_Smoke

Change-Id: I5f8f5c524c8a8854cde0d4f183901fc0a23bf0df
Reviewed-on: http://gerrit.chromium.org/gerrit/1081
Tested-by: Chris Masone <cmasone@chromium.org>
Reviewed-by: Zelidrag Hornung <zelidrag@chromium.org>
diff --git a/session_manager_service.cc b/session_manager_service.cc
index b5765cf..a8cb7e9 100644
--- a/session_manager_service.cc
+++ b/session_manager_service.cc
@@ -323,6 +323,7 @@
 }
 
 bool SessionManagerService::Shutdown() {
+  DeregisterChildWatchers();
   if (session_started_) {
     DLOG(INFO) << "emitting D-Bus signal SessionStateChanged:stopped";
     if (signals_[kSignalSessionStateChanged]) {
@@ -610,6 +611,7 @@
                   ServiceShutdown,
                   this,
                   NULL);
+  DeregisterChildWatchers();
   // TODO(cmasone): re-enable these when we try to enable logout without exiting
   //                the session manager
   // child_job_->StopSession();
@@ -1204,10 +1206,6 @@
 }
 
 void SessionManagerService::CleanupChildren(int timeout) {
-  // Remove child exit handlers.
-  for (size_t i = 0; i < child_watchers_.size(); ++i)
-    g_source_remove(child_watchers_[i]);
-
   vector<pair<int, uid_t> > pids_to_kill;
 
   for (size_t i = 0; i < child_pids_.size(); ++i) {
@@ -1233,6 +1231,13 @@
   }
 }
 
+void SessionManagerService::DeregisterChildWatchers() {
+  // Remove child exit handlers.
+  for (size_t i = 0; i < child_watchers_.size(); ++i)
+    g_source_remove(child_watchers_[i]);
+  child_watchers_.clear();
+}
+
 gboolean SessionManagerService::StoreOwnerProperties(GError** error) {
   if (!SignAndStoreProperty(kDeviceOwnerPref,
                             current_user_,
diff --git a/session_manager_service.h b/session_manager_service.h
index cd7b10e..dcecb66 100644
--- a/session_manager_service.h
+++ b/session_manager_service.h
@@ -399,6 +399,9 @@
   // Terminate all children, with increasing prejudice.
   void CleanupChildren(int timeout);
 
+  // De-register all child-exit handlers.
+  void DeregisterChildWatchers();
+
   // Assuming the current user has access to the owner private key
   // (read: is the owner), this call whitelists |current_user_|, sets a
   // property indicating |current_user_| is the owner, and schedules both