File: env_chromium.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (336 lines) | stat: -rw-r--r-- 13,110 bytes parent folder | download | duplicates (9)
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
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
// Copyright (c) 2013 The LevelDB Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. See the AUTHORS file for names of contributors.

#ifndef THIRD_PARTY_LEVELDATABASE_ENV_CHROMIUM_H_
#define THIRD_PARTY_LEVELDATABASE_ENV_CHROMIUM_H_

#include <memory>
#include <string>
#include <string_view>
#include <vector>

#include "base/containers/linked_list.h"
#include "base/containers/span.h"
#include "base/files/file.h"
#include "base/files/file_path.h"
#include "base/functional/callback.h"
#include "base/gtest_prod_util.h"
#include "base/synchronization/lock.h"
#include "base/thread_annotations.h"
#include "leveldb/cache.h"
#include "leveldb/db.h"
#include "leveldb/env.h"
#include "leveldb/export.h"
#include "port/port_chromium.h"

namespace base {
namespace trace_event {
class MemoryAllocatorDump;
class ProcessMemoryDump;
}  // namespace trace_event
}  // namespace base

namespace storage {
class FilesystemProxy;
}

namespace leveldb_env {

// These entries map to values in tools/metrics/histograms/histograms.xml. New
// values should be appended at the end.
enum MethodID {
  kSequentialFileRead,
  kSequentialFileSkip,
  kRandomAccessFileRead,
  kWritableFileAppend,
  kWritableFileClose,
  kWritableFileFlush,
  kWritableFileSync,
  kNewSequentialFile,
  kNewRandomAccessFile,
  kNewWritableFile,
  kObsoleteDeleteFile,
  kCreateDir,
  kObsoleteDeleteDir,
  kGetFileSize,
  kRenameFile,
  kLockFile,
  kUnlockFile,
  kGetTestDirectory,
  kNewLogger,
  kSyncParent,
  kGetChildren,
  kNewAppendableFile,
  kRemoveFile,
  kRemoveDir,
  kNumEntries
};

// leveldb::Status::Code values are mapped to these values for UMA logging.
// Do not change/delete these values as you will break reporting for older
// copies of Chrome. Only add new values to the end.
enum LevelDBStatusValue {
  LEVELDB_STATUS_OK = 0,
  LEVELDB_STATUS_NOT_FOUND,
  LEVELDB_STATUS_CORRUPTION,
  LEVELDB_STATUS_NOT_SUPPORTED,
  LEVELDB_STATUS_INVALID_ARGUMENT,
  LEVELDB_STATUS_IO_ERROR,
  LEVELDB_STATUS_MAX
};

LEVELDB_EXPORT LevelDBStatusValue
GetLevelDBStatusUMAValue(const leveldb::Status& s);

using DatabaseErrorReportingCallback =
    base::RepeatingCallback<void(const leveldb::Status&)>;

// Create the default leveldb options object suitable for leveldb operations.
struct LEVELDB_EXPORT Options : public leveldb::Options {
  Options();

  // Called when there is a error during the Get() call. Intended for metrics
  // reporting.
  DatabaseErrorReportingCallback on_get_error;
  // Called when there is a error during the Write() call, which is called for
  // Write(), Put() and Delete(). Intended for metrics reporting.
  DatabaseErrorReportingCallback on_write_error;
};

LEVELDB_EXPORT const char* MethodIDToString(MethodID method);

leveldb::Status LEVELDB_EXPORT
MakeIOError(leveldb::Slice filename,
            const std::string& message,
            MethodID method,
            base::File::Error error = base::File::FILE_OK);

enum ErrorParsingResult {
  METHOD_ONLY,
  METHOD_AND_BFE,
  NONE,
};

ErrorParsingResult LEVELDB_EXPORT
ParseMethodAndError(const leveldb::Status& status,
                    MethodID* method,
                    base::File::Error* error);
LEVELDB_EXPORT int GetCorruptionCode(const leveldb::Status& status);
LEVELDB_EXPORT int GetNumCorruptionCodes();
LEVELDB_EXPORT std::string GetCorruptionMessage(const leveldb::Status& status);
LEVELDB_EXPORT bool IndicatesDiskFull(const leveldb::Status& status);

// Returns the name for a temporary database copy during RewriteDB().
LEVELDB_EXPORT std::string DatabaseNameForRewriteDB(
    const std::string& original_name);

// Determine the appropriate leveldb write buffer size to use. The default size
// (4MB) may result in a log file too large to be compacted given the available
// storage space. This function will return smaller values for smaller disks,
// and the default leveldb value for larger disks.
//
// |disk_space| is the logical partition size (in bytes), and *not* available
// space. A value of -1 will return leveldb's default write buffer size.
LEVELDB_EXPORT extern size_t WriteBufferSize(int64_t disk_space);

// Thread safety: `ChromiumEnv` is safe to use from multiple threads as long as
// it's created and destroyed safely. In Chromium, ChromiumEnv is created via a
// NoDestructor singleton, so as a function-local static, construction is
// thread-safe as of C++11. The NoDestructor-wrapped instance is never
// destroyed.
class LEVELDB_EXPORT ChromiumEnv : public leveldb::Env {
 public:
  using ScheduleFunc = void(void*);

  // Constructs a ChromiumEnv instance with an unrestricted FilesystemProxy
  // instance that performs direct filesystem access.
  ChromiumEnv();

  // Temporary debugging ctor.
  explicit ChromiumEnv(bool log_lock_errors);

  // Constructs a ChromiumEnv instance with a custom FilesystemProxy instance.
  explicit ChromiumEnv(std::unique_ptr<storage::FilesystemProxy> filesystem);

  ~ChromiumEnv() override;

  bool FileExists(const std::string& fname) override;
  leveldb::Status GetChildren(const std::string& dir,
                              std::vector<std::string>* result) override;
  leveldb::Status RemoveFile(const std::string& fname) override;
  leveldb::Status CreateDir(const std::string& name) override;
  leveldb::Status RemoveDir(const std::string& name) override;
  leveldb::Status GetFileSize(const std::string& fname,
                              uint64_t* size) override;
  leveldb::Status RenameFile(const std::string& src,
                             const std::string& dst) override;
  leveldb::Status LockFile(const std::string& fname,
                           leveldb::FileLock** lock) override;
  leveldb::Status UnlockFile(leveldb::FileLock* lock) override;
  void Schedule(ScheduleFunc*, void* arg) override;
  void StartThread(void (*function)(void* arg), void* arg) override;
  leveldb::Status GetTestDirectory(std::string* path) override;
  uint64_t NowMicros() override;
  void SleepForMicroseconds(int micros) override;
  leveldb::Status NewSequentialFile(const std::string& fname,
                                    leveldb::SequentialFile** result) override;
  leveldb::Status NewRandomAccessFile(
      const std::string& fname,
      leveldb::RandomAccessFile** result) override;
  leveldb::Status NewWritableFile(const std::string& fname,
                                  leveldb::WritableFile** result) override;
  leveldb::Status NewAppendableFile(const std::string& fname,
                                    leveldb::WritableFile** result) override;
  leveldb::Status NewLogger(const std::string& fname,
                            leveldb::Logger** result) override;
  void SetReadOnlyFileLimitForTesting(int max_open_files);

 protected:
  static const char* FileErrorString(base::File::Error error);

 private:
  void RemoveBackupFiles(const base::FilePath& dir);

  // When `log_lock_errors_` is true, this env will emit extra metrics for
  // locking failures. TODO(crbug.com/340398745): remove this.
  bool log_lock_errors_ = false;

  // `FilesystemProxy` is thread-safe.
  const std::unique_ptr<storage::FilesystemProxy> filesystem_;

  base::Lock mu_;
  base::FilePath test_directory_ GUARDED_BY(mu_);

  // `leveldb::Cache` is thread-safe.
  std::unique_ptr<leveldb::Cache> file_cache_;
};

// Tracks databases open via OpenDatabase() method and exposes them to
// memory-infra. The class is thread safe.
class LEVELDB_EXPORT DBTracker {
 public:
  enum SharedReadCacheUse : int {
    // Use for databases whose access pattern is dictated by browser code.
    SharedReadCacheUse_Browser = 0,
    // Use for databases whose access pattern is directly influenced by Web
    // APIs, like Indexed DB, etc.
    SharedReadCacheUse_Web,
    SharedReadCacheUse_Unified,   // When Web == Browser.
    SharedReadCacheUse_InMemory,  // Shared by all in-memory databases.
    SharedReadCacheUse_NumCacheUses
  };

  // DBTracker singleton instance.
  static DBTracker* GetInstance();

  DBTracker(const DBTracker&) = delete;
  DBTracker& operator=(const DBTracker&) = delete;

  // Returns the memory-infra dump for |tracked_db|. Can be used to attach
  // additional info to the database dump, or to properly attribute memory
  // usage in memory dump providers that also dump |tracked_db|.
  // Note that |tracked_db| should be a live database instance produced by
  // OpenDatabase() method or leveldb_env::OpenDB() function.
  static base::trace_event::MemoryAllocatorDump* GetOrCreateAllocatorDump(
      base::trace_event::ProcessMemoryDump* pmd,
      leveldb::DB* tracked_db);

  // Returns the memory-infra dump for |tracked_memenv|. Can be used to attach
  // additional info to the database dump, or to properly attribute memory
  // usage in memory dump providers that also dump |tracked_memenv|.
  // Note that |tracked_memenv| should be a live Env instance produced by
  // leveldb_chrome::NewMemEnv().
  static base::trace_event::MemoryAllocatorDump* GetOrCreateAllocatorDump(
      base::trace_event::ProcessMemoryDump* pmd,
      leveldb::Env* tracked_memenv);

  // Provides extra information about a tracked database.
  class TrackedDB : public leveldb::DB {
   public:
    // Name that OpenDatabase() was called with.
    virtual const std::string& name() const = 0;

    // Options used when opening the database.
    virtual SharedReadCacheUse block_cache_type() const = 0;
  };

  // Opens a database and starts tracking it. As long as the opened database
  // is alive (i.e. its instance is not destroyed) the database is exposed to
  // memory-infra and is enumerated by VisitDatabases() method.
  // This function is an implementation detail of leveldb_env::OpenDB(), and
  // has similar guarantees regarding |dbptr| argument.
  leveldb::Status OpenDatabase(const leveldb_env::Options& options,
                               const std::string& name,
                               TrackedDB** dbptr);

 private:
  class MemoryDumpProvider;
  class TrackedDBImpl;

  using DatabaseVisitor = base::RepeatingCallback<void(TrackedDB*)>;

  friend class ChromiumEnvDBTrackerTest;
  FRIEND_TEST_ALL_PREFIXES(ChromiumEnvDBTrackerTest, IsTrackedDB);
  FRIEND_TEST_ALL_PREFIXES(ChromiumEnvDBTrackerTest, MemoryDumpCreation);
  FRIEND_TEST_ALL_PREFIXES(ChromiumEnvDBTrackerTest, MemEnvMemoryDumpCreation);

  DBTracker();
  ~DBTracker();

  // Calls |visitor| for each live database. The database is live from the
  // point it was returned from OpenDatabase() and up until its instance is
  // destroyed.
  // The databases may be visited in an arbitrary order.
  // This function takes a lock, preventing any database from being opened or
  // destroyed (but doesn't lock the databases themselves).
  void VisitDatabases(const DatabaseVisitor& visitor);

  // Checks if |db| is tracked.
  bool IsTrackedDB(const leveldb::DB* db) const;

  void DatabaseOpened(TrackedDBImpl* database);
  void DatabaseDestroyed(TrackedDBImpl* database);

  // Protect databases_ and mdp_ members.
  mutable base::Lock databases_lock_;
  base::LinkedList<TrackedDBImpl> databases_;
  std::unique_ptr<MemoryDumpProvider> mdp_;
};

// Opens a database with the specified "name" and "options" (see note) and
// exposes it to Chrome's tracing (see DBTracker for details). The function
// guarantees that:
//   1. |dbptr| is not touched on failure
//   2. |dbptr| is not NULL on success
//
// Note that some `options` may not be honored, for example in the case of
// in-memory databases, the block cache is disabled and a minimum write buffer
// size is used to conserve memory.
LEVELDB_EXPORT leveldb::Status OpenDB(const leveldb_env::Options& options,
                                      const std::string& name,
                                      std::unique_ptr<leveldb::DB>* dbptr);

// Overrides OpenDB with the given closure.
using DBFactoryMethod =
    base::RepeatingCallback<leveldb::Status(const leveldb_env::Options&,
                                            const std::string&,
                                            std::unique_ptr<leveldb::DB>*)>;
LEVELDB_EXPORT void SetDBFactoryForTesting(DBFactoryMethod factory);

// Copies the content of |dbptr| into a fresh database to remove traces of
// deleted data. |options| and |name| of the old database are required to create
// an identical copy. |dbptr| will be replaced with the new database on success.
// If the rewrite fails e.g. because we can't write to the temporary location,
// the old db is returned if possible, otherwise |*dbptr| can become NULL.
LEVELDB_EXPORT leveldb::Status RewriteDB(const leveldb_env::Options& options,
                                         const std::string& name,
                                         std::unique_ptr<leveldb::DB>* dbptr);

LEVELDB_EXPORT std::string_view MakeStringView(const leveldb::Slice& s);
LEVELDB_EXPORT leveldb::Slice MakeSlice(std::string_view s);
LEVELDB_EXPORT leveldb::Slice MakeSlice(base::span<const uint8_t> s);

}  // namespace leveldb_env

#endif  // THIRD_PARTY_LEVELDATABASE_ENV_CHROMIUM_H_