1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "sync/engine/model_changing_syncer_command.h"
6
7#include "base/basictypes.h"
8#include "base/bind.h"
9#include "base/bind_helpers.h"
10#include "sync/sessions/status_controller.h"
11#include "sync/sessions/sync_session.h"
12
13namespace syncer {
14
15SyncerError ModelChangingSyncerCommand::ExecuteImpl(
16    sessions::SyncSession* session) {
17  work_session_ = session;
18  SyncerError result = SYNCER_OK;
19
20  const std::set<ModelSafeGroup>& groups_to_change =
21      GetGroupsToChange(*work_session_);
22  for (size_t i = 0; i < session->context()->workers().size(); ++i) {
23    ModelSafeWorker* worker = session->context()->workers()[i].get();
24    ModelSafeGroup group = worker->GetModelSafeGroup();
25    // Skip workers whose group isn't active.
26    if (groups_to_change.count(group) == 0u) {
27      DVLOG(2) << "Skipping worker for group "
28               << ModelSafeGroupToString(group);
29      continue;
30    }
31
32    sessions::StatusController* status =
33        work_session_->mutable_status_controller();
34    sessions::ScopedModelSafeGroupRestriction r(status, group);
35    WorkCallback c = base::Bind(
36        &ModelChangingSyncerCommand::StartChangingModel,
37        // We wait until the callback is executed. So it is safe to use
38        // unretained.
39        base::Unretained(this));
40
41    SyncerError this_worker_result = worker->DoWorkAndWaitUntilDone(c);
42    // TODO(rlarocque): Figure out a better way to deal with errors from
43    // multiple models at once.  See also: crbug.com/109422.
44    if (this_worker_result != SYNCER_OK)
45      result = this_worker_result;
46  }
47
48  return result;
49}
50
51}  // namespace syncer
52