summaryrefslogtreecommitdiffstats
path: root/dom/localstorage/PBackgroundLSDatabase.ipdl
blob: 9a4402c97edbc4d58f3e108f83cf2fca0bbb31e2 (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
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
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */

include protocol PBackground;
include protocol PBackgroundLSSnapshot;

include PBackgroundLSSharedTypes;

include "mozilla/dom/localstorage/SerializationHelpers.h";

using mozilla::dom::LSSnapshot::LoadState
  from "mozilla/dom/LSSnapshot.h";

namespace mozilla {
namespace dom {

/**
 * Initial LSSnapshot state as produced by Datastore::GetSnapshotLoadInfo.  See
 * `LSSnapshot::LoadState` for more details about the possible states and a
 * high level overview.
 */
struct LSSnapshotInitInfo
{
  /**
   * Boolean indicating whether the `key` provided as an argument to the
   * PBackgroundLSSnapshot constructor did not exist in the Datastore and should
   * be treated as an unknown and therefore undefined value. Note that `key` may
   * have been provided as a void string, in which case this value is forced to
   * be false.
   */
  bool addKeyToUnknownItems;

  /**
   * As many key/value or key/void pairs as the snapshot prefill byte budget
   * allowed.
   */
  LSItemInfo[] itemInfos;

  /**
   * The total number of key/value pairs in LocalStorage for this origin at the
   * time the snapshot was created.  (And the point of the snapshot is to
   * conceptually freeze the state of the Datastore in time, so this value does
   * not change despite what other LSDatabase objects get up to in other
   * processes.)
   */
  uint32_t totalLength;

  /**
   * The current amount of LocalStorage usage as measured by the summing the
   * nsString Length() of both the key and the value over all stored pairs.
   */
  int64_t usage;

  /**
   * The amount of storage allowed to be used by the Snapshot without requesting
   * more storage space via IncreasePeakUsage.  This is the `usage` plus 0 or
   * more bytes of space.  If space was available, the increase will be the
   * `minSize` from the PBackgroundLSSnapshot constructor plus the configured
   * pre-increment (via "dom.storage.snapshot_peak_usage.initial_preincrement").
   * If the LocalStorage total usage was already close to the limit, then the
   * fallback is either the `minSize` plus the configured reduced pre-increment
   * (via "dom.storage.snapshot_peak_usage.reduced_initial_preincrement"), or
   * `minSize`, or 0 depending on remaining available space.
   */
  int64_t peakUsage;

  // See `LSSnapshot::LoadState` in `LSSnapshot.h`
  LoadState loadState;

  /**
   * Boolean indicating whether there where cross-process databases registered
   * for this origin at the time the snapshot was created.
   */
  bool hasOtherProcessDatabases;

  /**
   * Boolean indicating whether there where cross-process observers registered
   * for this origin at the time the snapshot was created.
   */
  bool hasOtherProcessObservers;
};

/**
 * This protocol is asynchronously created via constructor on PBackground but
 * has synchronous semantics from the perspective of content on the main thread.
 * The construction potentially involves waiting for disk I/O to load the
 * LocalStorage data from disk as well as related QuotaManager checks, so async
 * calls to PBackground are the only viable mechanism because blocking
 * PBackground is not acceptable.  (Note that an attempt is made to minimize any
 * I/O latency by triggering preloading from
 * ContentParent::AboutToLoadHttpFtpDocumentForChild, the central place
 * for pre-loading.)
 */
[ManualDealloc, ChildImpl=virtual, ParentImpl=virtual]
sync protocol PBackgroundLSDatabase
{
  manager PBackground;
  manages PBackgroundLSSnapshot;

parent:
  // The DeleteMe message is used to avoid a race condition between the parent
  // actor and the child actor. The PBackgroundLSDatabase protocol could be
  // simply destroyed by sending the __delete__ message from the child side.
  // However, that would destroy the child actor immediatelly and the parent
  // could be sending a message to the child at the same time resulting in a
  // routing error since the child actor wouldn't exist anymore. A routing
  // error typically causes a crash. The race can be prevented by doing the
  // teardown in two steps. First, we send the DeleteMe message to the parent
  // and the parent then sends the __delete__ message to the child.
  async DeleteMe();

  /**
   * Sent in response to a `RequestAllowToClose` message once the snapshot
   * cleanup has happened OR from LSDatabase's destructor if AllowToClose has
   * not already been reported.
   */
  async AllowToClose();

  /**
   * Invoked to create an LSSnapshot backed by a Snapshot in PBackground that
   * presents an atomic and consistent view of the state of the authoritative
   * Datastore state in the parent.
   *
   * This needs to be synchronous because LocalStorage's semantics are
   * synchronous.  Note that the Datastore in the PBackground parent already
   * has the answers to this request immediately available without needing to
   * consult any other threads or perform any I/O.  Additionally, the response
   * is explicitly bounded in size by the tunable snapshot prefill byte limit.
   *
   * @param key
   *   If key is non-void, then the snapshot is being triggered by a direct
   *   access to a localStorage key (get, set, or removal, with set/removal
   *   requiring the old value in order to properly populate the "storage"
   *   event), the key being requested. It's possible the key is not present in
   *   localStorage, in which case LSSnapshotInitInfo::addKeyToUnknownItems will
   *   be true indicating that there is no such key/value pair, otherwise it
   *   will be false.
   * @param increasePeakUsage
   *   Whether the parent should increase initial peak uage of the Snapshot.
   *   See also the comment for LSSnapshotInitInfo::peakUsage above.
   */
  sync PBackgroundLSSnapshot(nsString documentURI,
                             nsString key,
                             bool increasePeakUsage,
                             int64_t minSize)
    returns (LSSnapshotInitInfo initInfo);

child:
  /**
   * Only sent by the parent in response to the child's DeleteMe request.
   */
  async __delete__();

  /**
   * Request to close the LSDatabase, checkpointing and finishing any
   * outstanding snapshots so no state is lost.  This request is issued when
   * QuotaManager is shutting down or is aborting operations for an origin or
   * process.  Once the snapshot has cleaned up, AllowToClose will be sent to
   * the parent.
   *
   * Note that the QuotaManager shutdown process is more likely to happen in
   * unit tests where we explicitly reset the QuotaManager.  At runtime, we
   * expect windows to be closed and content processes terminated well before
   * QuotaManager shutdown would actually occur.
   *
   * Also, Operations are usually aborted for an origin due to privacy API's
   * clearing data for an origin.  Operations are aborted for a process by
   * ContentParent::ShutDownProcess.
   */
  async RequestAllowToClose();
};

} // namespace dom
} // namespace mozilla