1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "mozilla/dom/cache/StreamList.h"
10 #include "mozilla/dom/cache/CacheStreamControlParent.h"
11 #include "mozilla/dom/cache/Context.h"
12 #include "mozilla/dom/cache/Manager.h"
13 #include "nsIInputStream.h"
15 namespace mozilla::dom::cache
{
19 auto MatchById(const nsID
& aId
) {
20 return [aId
](const auto& entry
) { return entry
.mId
== aId
; };
25 StreamList::StreamList(SafeRefPtr
<Manager
> aManager
,
26 SafeRefPtr
<Context
> aContext
)
27 : mManager(std::move(aManager
)),
28 mContext(std::move(aContext
)),
29 mCacheId(INVALID_CACHE_ID
),
30 mStreamControl(nullptr),
32 MOZ_DIAGNOSTIC_ASSERT(mManager
);
33 mContext
->AddActivity(*this);
36 Manager
& StreamList::GetManager() const {
37 MOZ_DIAGNOSTIC_ASSERT(mManager
);
41 bool StreamList::ShouldOpenStreamFor(const nsID
& aId
) const {
42 NS_ASSERT_OWNINGTHREAD(StreamList
);
44 return std::any_of(mList
.cbegin(), mList
.cend(), MatchById(aId
));
47 void StreamList::SetStreamControl(CacheStreamControlParent
* aStreamControl
) {
48 NS_ASSERT_OWNINGTHREAD(StreamList
);
49 MOZ_DIAGNOSTIC_ASSERT(aStreamControl
);
51 // For cases where multiple streams are serialized for a single list
52 // then the control will get passed multiple times. This is ok, but
53 // it should be the same control each time.
55 MOZ_DIAGNOSTIC_ASSERT(aStreamControl
== mStreamControl
);
59 mStreamControl
= aStreamControl
;
60 mStreamControl
->SetStreamList(SafeRefPtrFromThis());
63 void StreamList::RemoveStreamControl(CacheStreamControlParent
* aStreamControl
) {
64 NS_ASSERT_OWNINGTHREAD(StreamList
);
65 MOZ_DIAGNOSTIC_ASSERT(mStreamControl
);
66 MOZ_DIAGNOSTIC_ASSERT(mStreamControl
== aStreamControl
);
67 mStreamControl
= nullptr;
70 void StreamList::Activate(CacheId aCacheId
) {
71 NS_ASSERT_OWNINGTHREAD(StreamList
);
72 MOZ_DIAGNOSTIC_ASSERT(!mActivated
);
73 MOZ_DIAGNOSTIC_ASSERT(mCacheId
== INVALID_CACHE_ID
);
76 mManager
->AddRefCacheId(mCacheId
);
77 mManager
->AddStreamList(*this);
79 for (uint32_t i
= 0; i
< mList
.Length(); ++i
) {
80 mManager
->AddRefBodyId(mList
[i
].mId
);
84 void StreamList::Add(const nsID
& aId
, nsCOMPtr
<nsIInputStream
>&& aStream
) {
85 // All streams should be added on IO thread before we set the stream
86 // control on the owning IPC thread.
87 MOZ_DIAGNOSTIC_ASSERT(!mStreamControl
);
88 mList
.EmplaceBack(aId
, std::move(aStream
));
91 already_AddRefed
<nsIInputStream
> StreamList::Extract(const nsID
& aId
) {
92 NS_ASSERT_OWNINGTHREAD(StreamList
);
94 const auto it
= std::find_if(mList
.begin(), mList
.end(), MatchById(aId
));
96 return it
!= mList
.end() ? it
->mStream
.forget() : nullptr;
99 void StreamList::NoteClosed(const nsID
& aId
) {
100 NS_ASSERT_OWNINGTHREAD(StreamList
);
102 const auto it
= std::find_if(mList
.begin(), mList
.end(), MatchById(aId
));
103 if (it
!= mList
.end()) {
104 mList
.RemoveElementAt(it
);
105 mManager
->ReleaseBodyId(aId
);
108 if (mList
.IsEmpty() && mStreamControl
) {
109 mStreamControl
->Shutdown();
113 void StreamList::NoteClosedAll() {
114 NS_ASSERT_OWNINGTHREAD(StreamList
);
115 for (uint32_t i
= 0; i
< mList
.Length(); ++i
) {
116 mManager
->ReleaseBodyId(mList
[i
].mId
);
120 if (mStreamControl
) {
121 mStreamControl
->Shutdown();
125 void StreamList::CloseAll() {
126 NS_ASSERT_OWNINGTHREAD(StreamList
);
127 if (mStreamControl
) {
128 auto* streamControl
= std::exchange(mStreamControl
, nullptr);
130 streamControl
->CloseAll();
132 mStreamControl
= std::exchange(streamControl
, nullptr);
134 mStreamControl
->Shutdown();
138 void StreamList::Cancel() {
139 NS_ASSERT_OWNINGTHREAD(StreamList
);
143 bool StreamList::MatchesCacheId(CacheId aCacheId
) const {
144 NS_ASSERT_OWNINGTHREAD(StreamList
);
145 return aCacheId
== mCacheId
;
148 StreamList::~StreamList() {
149 NS_ASSERT_OWNINGTHREAD(StreamList
);
150 MOZ_DIAGNOSTIC_ASSERT(!mStreamControl
);
152 mManager
->RemoveStreamList(*this);
153 for (uint32_t i
= 0; i
< mList
.Length(); ++i
) {
154 mManager
->ReleaseBodyId(mList
[i
].mId
);
156 mManager
->ReleaseCacheId(mCacheId
);
158 mContext
->RemoveActivity(*this);
161 } // namespace mozilla::dom::cache