summaryrefslogtreecommitdiffstats
path: root/chrome/browser/sync/syncable/directory_manager.h
blob: 103ec306b3fac83271058165efa8f94525ae15fb (plain)
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
// Copyright (c) 2009 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.
//
// This used to do a lot of TLS-based management of multiple Directory objects.
// We now can access Directory objects from any thread for general purpose
// operations and we only ever have one Directory, so this class isn't doing
// anything too fancy besides keeping calling and access conventions the same
// for now.
// TODO(timsteele): We can probably nuke this entire class and use raw
// Directory objects everywhere.
#ifndef CHROME_BROWSER_SYNC_SYNCABLE_DIRECTORY_MANAGER_H_
#define CHROME_BROWSER_SYNC_SYNCABLE_DIRECTORY_MANAGER_H_

#include <string>
#include <vector>

#include "base/atomicops.h"
#include "base/basictypes.h"
#include "base/file_path.h"
#include "base/lock.h"
#include "chrome/browser/sync/syncable/dir_open_result.h"
#include "chrome/browser/sync/syncable/path_name_cmp.h"
#include "chrome/browser/sync/syncable/syncable.h"
#include "chrome/browser/sync/util/cryptographer.h"
#include "chrome/browser/sync/util/sync_types.h"
#include "chrome/common/deprecated/event_sys.h"

namespace sync_api { class BaseTransaction; }

namespace syncable {

struct DirectoryManagerEvent {
  enum {
    OPEN_FAILED,
    OPENED,
    CLOSED,
    CLOSED_ALL,
    SHUTDOWN,
  } what_happened;
  std::string dirname;
  DirOpenResult error;  // Only for OPEN_FAILED.
  typedef DirectoryManagerEvent EventType;
  static inline bool IsChannelShutdownEvent(const EventType& event) {
    return SHUTDOWN == event.what_happened;
  }
};

DirectoryManagerEvent DirectoryManagerShutdownEvent();

class DirectoryManager {
 public:
  typedef EventChannel<DirectoryManagerEvent> Channel;

  // root_path specifies where db is stored.
  explicit DirectoryManager(const FilePath& root_path);
  virtual ~DirectoryManager();

  static const FilePath GetSyncDataDatabaseFilename();
  const FilePath GetSyncDataDatabasePath() const;

  // Opens a directory.  Returns false on error.
  // Name parameter is the the user's login,
  // MUST already have been converted to a common case.
  bool Open(const std::string& name);

  // Marks a directory as closed.  It might take a while until all the
  // file handles and resources are freed by other threads.
  void Close(const std::string& name);

  // Should be called at App exit.
  void FinalSaveChangesForAll();

  // Gets the list of currently open directory names.
  typedef std::vector<std::string> DirNames;
  void GetOpenDirectories(DirNames* result);

  Channel* channel() const { return channel_; }

  browser_sync::Cryptographer* cryptographer() const {
    return cryptographer_.get();
  }

 protected:
  DirOpenResult OpenImpl(const std::string& name, const FilePath& path,
                         bool* was_open);

  // Helpers for friend class ScopedDirLookup:
  friend class ScopedDirLookup;

  const FilePath root_path_;

  // protects managed_directory_
  Lock lock_;
  Directory* managed_directory_;

  Channel* const channel_;

  scoped_ptr<browser_sync::Cryptographer> cryptographer_;

 private:
  DISALLOW_COPY_AND_ASSIGN(DirectoryManager);
};


class ScopedDirLookup {
 public:
  ScopedDirLookup(DirectoryManager* dirman, const std::string& name);
  ~ScopedDirLookup();

  inline bool good() {
    good_checked_ = true;
    return good_;
  }
  Directory* operator -> () const;
  operator Directory* () const;

 protected:  // Don't allow creation on heap, except by sync API wrapper.
  friend class sync_api::BaseTransaction;
  void* operator new(size_t size) { return (::operator new)(size); }

  Directory* dir_;
  bool good_;
  // Ensure that the programmer checks good before using the ScopedDirLookup.
  // This member should can be removed if it ever shows up in profiling
  bool good_checked_;
  DirectoryManager* const dirman_;
};

}  // namespace syncable

#endif  // CHROME_BROWSER_SYNC_SYNCABLE_DIRECTORY_MANAGER_H_