File: shared_change_processor.h

package info (click to toggle)
chromium-browser 57.0.2987.98-1~deb8u1
  • links: PTS, VCS
  • area: main
  • in suites: jessie
  • size: 2,637,852 kB
  • ctags: 2,544,394
  • sloc: cpp: 12,815,961; ansic: 3,676,222; python: 1,147,112; asm: 526,608; java: 523,212; xml: 286,794; perl: 92,654; sh: 86,408; objc: 73,271; makefile: 27,698; cs: 18,487; yacc: 13,031; tcl: 12,957; pascal: 4,875; ml: 4,716; lex: 3,904; sql: 3,862; ruby: 1,982; lisp: 1,508; php: 1,368; exp: 404; awk: 325; csh: 117; jsp: 39; sed: 37
file content (165 lines) | stat: -rw-r--r-- 7,022 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef COMPONENTS_SYNC_DRIVER_SHARED_CHANGE_PROCESSOR_H_
#define COMPONENTS_SYNC_DRIVER_SHARED_CHANGE_PROCESSOR_H_

#include <memory>
#include <string>

#include "base/location.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/sequenced_task_runner.h"
#include "base/single_thread_task_runner.h"
#include "base/synchronization/lock.h"
#include "components/sync/driver/data_type_controller.h"
#include "components/sync/engine/model_safe_worker.h"
#include "components/sync/model/data_type_error_handler.h"
#include "components/sync/model/sync_change_processor.h"
#include "components/sync/model/sync_data.h"
#include "components/sync/model/sync_error.h"
#include "components/sync/model/sync_error_factory.h"
#include "components/sync/model/sync_merge_result.h"

namespace syncer {

class ChangeProcessor;
class GenericChangeProcessor;
class GenericChangeProcessorFactory;
class SyncClient;
class SyncableService;
struct UserShare;

// A ref-counted wrapper around a GenericChangeProcessor for use with datatypes
// that don't live on the UI thread.
//
// We need to make it refcounted as the ownership transfer from the
// DataTypeController is dependent on threading, and hence racy. The
// SharedChangeProcessor should be created on the UI thread, but should only be
// connected and used on the same thread as the datatype it interacts with.
//
// The only thread-safe method is Disconnect, which will disconnect from the
// generic change processor, letting us shut down the syncer/datatype without
// waiting for non-UI threads.
//
// Note: since we control the work being done while holding the lock, we ensure
// no I/O or other intensive work is done while blocking the UI thread (all
// the work is in-memory sync interactions).
//
// We use virtual methods so that we can use mock's in testing.
class SharedChangeProcessor
    : public base::RefCountedThreadSafe<SharedChangeProcessor> {
 public:
  typedef base::Callback<void(DataTypeController::ConfigureResult start_result,
                              const SyncMergeResult& local_merge_result,
                              const SyncMergeResult& syncer_merge_result)>
      StartDoneCallback;

  // Create an uninitialized SharedChangeProcessor.
  explicit SharedChangeProcessor(ModelType type);

  void StartAssociation(StartDoneCallback start_done,
                        SyncClient* const sync_client,
                        GenericChangeProcessorFactory* processor_factory,
                        UserShare* user_share,
                        std::unique_ptr<DataTypeErrorHandler> error_handler);

  // Connect to the Syncer and prepare to handle changes for |type|. Will
  // create and store a new GenericChangeProcessor and return a weak pointer to
  // the SyncableService associated with |type|.
  // Note: If this SharedChangeProcessor has been disconnected, or the
  // SyncableService was not alive, will return a null weak pointer.
  virtual base::WeakPtr<SyncableService> Connect(
      SyncClient* sync_client,
      GenericChangeProcessorFactory* processor_factory,
      UserShare* user_share,
      std::unique_ptr<DataTypeErrorHandler> error_handler,
      const base::WeakPtr<SyncMergeResult>& merge_result);

  // Disconnects from the generic change processor. This method is thread-safe.
  // After this, all attempts to interact with the change processor by
  // |local_service_| are dropped and return errors. The syncer will be safe to
  // shut down from the point of view of this datatype.
  // Note: Once disconnected, you cannot reconnect without creating a new
  // SharedChangeProcessor.
  // Returns: true if we were previously succesfully connected, false if we were
  // already disconnected.
  virtual bool Disconnect();

  // GenericChangeProcessor stubs (with disconnect support).
  // Should only be called on the same sequence the datatype resides.
  virtual int GetSyncCount();
  virtual SyncError ProcessSyncChanges(
      const tracked_objects::Location& from_here,
      const SyncChangeList& change_list);
  virtual SyncDataList GetAllSyncData(ModelType type) const;
  virtual SyncError GetAllSyncDataReturnError(ModelType type,
                                              SyncDataList* data) const;
  virtual SyncError UpdateDataTypeContext(
      ModelType type,
      SyncChangeProcessor::ContextRefreshStatus refresh_status,
      const std::string& context);
  virtual void AddLocalChangeObserver(LocalChangeObserver* observer);
  virtual void RemoveLocalChangeObserver(LocalChangeObserver* observer);
  virtual bool SyncModelHasUserCreatedNodes(bool* has_nodes);
  virtual bool CryptoReadyIfNecessary();

  // If a datatype context associated with the current type exists, fills
  // |context| and returns true. Otheriwse, if there has not been a context
  // set, returns false.
  virtual bool GetDataTypeContext(std::string* context) const;

  virtual SyncError CreateAndUploadError(
      const tracked_objects::Location& location,
      const std::string& message);

  // Calls local_service_->StopSyncing() and releases our reference to it.
  void StopLocalService();

  ChangeProcessor* generic_change_processor();

 protected:
  friend class base::RefCountedThreadSafe<SharedChangeProcessor>;
  virtual ~SharedChangeProcessor();

 private:
  // Record association time.
  virtual void RecordAssociationTime(base::TimeDelta time);

  // Monitor lock for this object. All methods that interact with the change
  // processor must aquire this lock and check whether we're disconnected or
  // not. Once disconnected, all attempted changes to or loads from the change
  // processor return errors. This enables us to shut down the syncer without
  // having to wait for possibly non-UI thread datatypes to complete work.
  mutable base::Lock monitor_lock_;
  bool disconnected_;

  // The sync datatype we process changes for.
  const ModelType type_;

  // The frontend / UI MessageLoop this object is constructed on. May also be
  // destructed and/or disconnected on this loop, see ~SharedChangeProcessor.
  const scoped_refptr<const base::SingleThreadTaskRunner> frontend_task_runner_;

  // The execution sequence that all methods except the constructor, destructor,
  // and Disconnect() should be called on. Set in Connect().
  scoped_refptr<base::SequencedTaskRunner> backend_task_runner_;

  // Used only on |backend_task_runner_|.
  GenericChangeProcessor* generic_change_processor_;

  std::unique_ptr<DataTypeErrorHandler> error_handler_;

  // The local service for this type. Only set if the DTC for the type uses
  // SharedChangeProcessor::StartAssociation().
  base::WeakPtr<SyncableService> local_service_;

  DISALLOW_COPY_AND_ASSIGN(SharedChangeProcessor);
};

}  // namespace syncer

#endif  // COMPONENTS_SYNC_DRIVER_SHARED_CHANGE_PROCESSOR_H_