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
content / browser / indexed_db / instance / active_blob_registry.h [blame]
// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CONTENT_BROWSER_INDEXED_DB_INSTANCE_ACTIVE_BLOB_REGISTRY_H_
#define CONTENT_BROWSER_INDEXED_DB_INSTANCE_ACTIVE_BLOB_REGISTRY_H_
#include <stdint.h>
#include <map>
#include <set>
#include <utility>
#include "base/functional/callback.h"
#include "base/memory/weak_ptr.h"
#include "base/sequence_checker.h"
#include "content/common/content_export.h"
namespace content::indexed_db {
// Keeps track of blobs that have been sent to clients as database responses,
// and determines when Blob files can be deleted. The database entry that links
// to the blob file can be deleted in the database, but the blob file still
// needs to stay alive while it is still active (i.e. referenced by a client).
// This class must be used on a single sequence, and will call the given
// callbacks back on the same sequence it is constructed on.
class CONTENT_EXPORT ActiveBlobRegistry {
public:
using ReportOutstandingBlobsCallback = base::RepeatingCallback<void(bool)>;
using ReportUnusedBlobCallback =
base::RepeatingCallback<void(int64_t /*database_id*/,
int64_t /*blob_number*/)>;
explicit ActiveBlobRegistry(
ReportOutstandingBlobsCallback report_outstanding_blobs,
ReportUnusedBlobCallback report_unused_blob);
ActiveBlobRegistry(const ActiveBlobRegistry&) = delete;
ActiveBlobRegistry& operator=(const ActiveBlobRegistry&) = delete;
~ActiveBlobRegistry();
// Most methods of this class, and the closure returned by
// GetMarkBlobActiveCallback, should only be called on the backing_store's
// task runner. The exception is the closure returned by
// GetFinalReleaseCallback, which just calls MarkBlobInactiveThreadSafe.
// Called when the given database is deleted (and all blob infos inside of
// it). Returns true if any of the deleted blobs are active (i.e. referenced
// by a client).
bool MarkDatabaseDeletedAndCheckIfReferenced(int64_t database_id);
// Called when the given blob handle is deleted by a transaction, and returns
// if the blob file has one or more external references.
bool MarkBlobInfoDeletedAndCheckIfReferenced(int64_t database_id,
int64_t blob_number);
// When called, the returned callback will mark the given blob entry as
// inactive (i.e. no longer referenced by a client).
// This closure must be called on the same sequence as this registry.
base::RepeatingClosure GetFinalReleaseCallback(int64_t database_id,
int64_t blob_number);
// When called, the returned closure will mark the given blob entry as active
// (i.e. referenced by the client). Calling this multiple times does nothing.
// This closure holds a raw pointer to the ActiveBlobRegistry, and may not be
// called after it is deleted.
base::RepeatingClosure GetMarkBlobActiveCallback(int64_t database_id,
int64_t blob_number);
// Call this to force the registry to drop its use counts, permitting the
// factory to drop any blob-related refcount for the backing store.
// This will also turn any outstanding callbacks into no-ops.
void ForceShutdown();
private:
enum class BlobState { kLinked, kUnlinked };
// Maps blob_number -> BlobState; if the record's absent, it's not in active
// use and we don't care if it's deleted.
typedef std::map<int64_t, BlobState> SingleDBMap;
void MarkBlobActive(int64_t database_id, int64_t blob_number);
// Removes a reference to the given blob.
void MarkBlobInactive(int64_t database_id, int64_t blob_number);
SEQUENCE_CHECKER(sequence_checker_);
// This stores, for every database, the blobs that are currently being used in
// that database.
std::map<int64_t, SingleDBMap> blob_reference_tracker_;
// Databases that have been marked as deleted by
// MarkDatabaseDeletedAndCheckIfReferenced.
std::set<int64_t> deleted_dbs_;
ReportOutstandingBlobsCallback report_outstanding_blobs_;
ReportUnusedBlobCallback report_unused_blob_;
base::WeakPtrFactory<ActiveBlobRegistry> weak_factory_{this};
};
} // namespace content::indexed_db
#endif // CONTENT_BROWSER_INDEXED_DB_INSTANCE_ACTIVE_BLOB_REGISTRY_H_