зеркало из https://github.com/mozilla/gecko-dev.git
Backed out changeset 99cce83b7e41 (bug 1636050) for assertion failures on ReadStream.cpp. CLOSED TREE
This commit is contained in:
Родитель
ea9bf8c0f4
Коммит
c644ee9a06
|
@ -62,14 +62,12 @@ class ReadStream::Inner final : public ReadStream::Controllable {
|
|||
|
||||
nsresult IsNonBlocking(bool* aNonBlockingOut);
|
||||
|
||||
NS_DECL_OWNINGTHREAD;
|
||||
|
||||
~Inner();
|
||||
|
||||
private:
|
||||
class NoteClosedRunnable;
|
||||
class ForgetRunnable;
|
||||
|
||||
~Inner();
|
||||
|
||||
void NoteClosed();
|
||||
|
||||
void Forget();
|
||||
|
@ -86,10 +84,6 @@ class ReadStream::Inner final : public ReadStream::Controllable {
|
|||
|
||||
void OpenStreamFailed();
|
||||
|
||||
inline SafeRefPtr<Inner> SafeRefPtrFromThis() {
|
||||
return Controllable::SafeRefPtrFromThis().downcast<Inner>();
|
||||
}
|
||||
|
||||
// Weak ref to the stream control actor. The actor will always call either
|
||||
// CloseStream() or CloseStreamWithoutReporting() before it's destroyed. The
|
||||
// weak ref is cleared in the resulting NoteClosedOnOwningThread() or
|
||||
|
@ -112,6 +106,8 @@ class ReadStream::Inner final : public ReadStream::Controllable {
|
|||
CondVar mCondVar;
|
||||
nsCOMPtr<nsIInputStream> mStream;
|
||||
nsCOMPtr<nsIInputStream> mSnappyStream;
|
||||
|
||||
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(cache::ReadStream::Inner, override)
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -122,12 +118,13 @@ class ReadStream::Inner final : public ReadStream::Controllable {
|
|||
// ReadStream is constructed on a child process Worker thread).
|
||||
class ReadStream::Inner::NoteClosedRunnable final : public CancelableRunnable {
|
||||
public:
|
||||
explicit NoteClosedRunnable(ReadStream::Inner& aStream)
|
||||
explicit NoteClosedRunnable(ReadStream::Inner* aStream)
|
||||
: CancelableRunnable("dom::cache::ReadStream::Inner::NoteClosedRunnable"),
|
||||
mStream(aStream) {}
|
||||
|
||||
NS_IMETHOD Run() override {
|
||||
mStream.NoteClosedOnOwningThread();
|
||||
mStream->NoteClosedOnOwningThread();
|
||||
mStream = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -141,7 +138,7 @@ class ReadStream::Inner::NoteClosedRunnable final : public CancelableRunnable {
|
|||
private:
|
||||
~NoteClosedRunnable() = default;
|
||||
|
||||
ReadStream::Inner& mStream;
|
||||
RefPtr<ReadStream::Inner> mStream;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -153,12 +150,13 @@ class ReadStream::Inner::NoteClosedRunnable final : public CancelableRunnable {
|
|||
// ReadStream is constructed on a child process Worker thread).
|
||||
class ReadStream::Inner::ForgetRunnable final : public CancelableRunnable {
|
||||
public:
|
||||
explicit ForgetRunnable(ReadStream::Inner& aStream)
|
||||
explicit ForgetRunnable(ReadStream::Inner* aStream)
|
||||
: CancelableRunnable("dom::cache::ReadStream::Inner::ForgetRunnable"),
|
||||
mStream(aStream) {}
|
||||
|
||||
NS_IMETHOD Run() override {
|
||||
mStream.ForgetOnOwningThread();
|
||||
mStream->ForgetOnOwningThread();
|
||||
mStream = nullptr;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -172,7 +170,7 @@ class ReadStream::Inner::ForgetRunnable final : public CancelableRunnable {
|
|||
private:
|
||||
~ForgetRunnable() = default;
|
||||
|
||||
ReadStream::Inner& mStream;
|
||||
RefPtr<ReadStream::Inner> mStream;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -191,7 +189,7 @@ ReadStream::Inner::Inner(StreamControl* aControl, const nsID& aId,
|
|||
mSnappyStream(aStream ? new SnappyUncompressInputStream(aStream)
|
||||
: nullptr) {
|
||||
MOZ_DIAGNOSTIC_ASSERT(mControl);
|
||||
mControl->AddReadStream(SafeRefPtrFromThis());
|
||||
mControl->AddReadStream(this);
|
||||
}
|
||||
|
||||
void ReadStream::Inner::Serialize(
|
||||
|
@ -366,7 +364,7 @@ void ReadStream::Inner::NoteClosed() {
|
|||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIRunnable> runnable = new NoteClosedRunnable(*this);
|
||||
nsCOMPtr<nsIRunnable> runnable = new NoteClosedRunnable(this);
|
||||
MOZ_ALWAYS_SUCCEEDS(mOwningEventTarget->Dispatch(runnable.forget(),
|
||||
nsIThread::DISPATCH_NORMAL));
|
||||
}
|
||||
|
@ -382,7 +380,7 @@ void ReadStream::Inner::Forget() {
|
|||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIRunnable> runnable = new ForgetRunnable(*this);
|
||||
nsCOMPtr<nsIRunnable> runnable = new ForgetRunnable(this);
|
||||
MOZ_ALWAYS_SUCCEEDS(mOwningEventTarget->Dispatch(runnable.forget(),
|
||||
nsIThread::DISPATCH_NORMAL));
|
||||
}
|
||||
|
@ -398,7 +396,7 @@ void ReadStream::Inner::NoteClosedOnOwningThread() {
|
|||
MaybeAbortAsyncOpenStream();
|
||||
|
||||
MOZ_DIAGNOSTIC_ASSERT(mControl);
|
||||
mControl->NoteClosed(SafeRefPtrFromThis(), mId);
|
||||
mControl->NoteClosed(this, mId);
|
||||
mControl = nullptr;
|
||||
}
|
||||
|
||||
|
@ -413,7 +411,7 @@ void ReadStream::Inner::ForgetOnOwningThread() {
|
|||
MaybeAbortAsyncOpenStream();
|
||||
|
||||
MOZ_DIAGNOSTIC_ASSERT(mControl);
|
||||
mControl->ForgetReadStream(SafeRefPtrFromThis());
|
||||
mControl->ForgetReadStream(this);
|
||||
mControl = nullptr;
|
||||
}
|
||||
|
||||
|
@ -554,8 +552,9 @@ already_AddRefed<ReadStream> ReadStream::Create(
|
|||
}
|
||||
#endif
|
||||
|
||||
return MakeAndAddRef<ReadStream>(MakeSafeRefPtr<ReadStream::Inner>(
|
||||
std::move(control), aReadStream.id(), stream));
|
||||
RefPtr<Inner> inner = new Inner(control, aReadStream.id(), stream);
|
||||
RefPtr<ReadStream> ref = new ReadStream(inner);
|
||||
return ref.forget();
|
||||
}
|
||||
|
||||
// static
|
||||
|
@ -563,9 +562,10 @@ already_AddRefed<ReadStream> ReadStream::Create(
|
|||
PCacheStreamControlParent* aControl, const nsID& aId,
|
||||
nsIInputStream* aStream) {
|
||||
MOZ_DIAGNOSTIC_ASSERT(aControl);
|
||||
|
||||
return MakeAndAddRef<ReadStream>(MakeSafeRefPtr<ReadStream::Inner>(
|
||||
static_cast<CacheStreamControlParent*>(aControl), aId, aStream));
|
||||
auto actor = static_cast<CacheStreamControlParent*>(aControl);
|
||||
RefPtr<Inner> inner = new Inner(actor, aId, aStream);
|
||||
RefPtr<ReadStream> ref = new ReadStream(inner);
|
||||
return ref.forget();
|
||||
}
|
||||
|
||||
void ReadStream::Serialize(
|
||||
|
@ -580,8 +580,7 @@ void ReadStream::Serialize(
|
|||
mInner->Serialize(aReadStreamOut, aStreamCleanupList, aRv);
|
||||
}
|
||||
|
||||
ReadStream::ReadStream(SafeRefPtr<ReadStream::Inner> aInner)
|
||||
: mInner(std::move(aInner)) {
|
||||
ReadStream::ReadStream(ReadStream::Inner* aInner) : mInner(aInner) {
|
||||
MOZ_DIAGNOSTIC_ASSERT(mInner);
|
||||
}
|
||||
|
||||
|
|
|
@ -49,10 +49,8 @@ class ReadStream final : public nsIInputStream {
|
|||
public:
|
||||
// Interface that lets the StreamControl classes interact with
|
||||
// our private inner stream.
|
||||
class Controllable : public SafeRefCounted<Controllable> {
|
||||
class Controllable {
|
||||
public:
|
||||
virtual ~Controllable() = default;
|
||||
|
||||
// Closes the stream, notifies the stream control, and then forgets
|
||||
// the stream control.
|
||||
virtual void CloseStream() = 0;
|
||||
|
@ -65,7 +63,7 @@ class ReadStream final : public nsIInputStream {
|
|||
|
||||
virtual bool HasEverBeenRead() const = 0;
|
||||
|
||||
MOZ_DECLARE_REFCOUNTED_TYPENAME(ReadStream::Controllable);
|
||||
NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING
|
||||
};
|
||||
|
||||
static already_AddRefed<ReadStream> Create(
|
||||
|
@ -90,6 +88,7 @@ class ReadStream final : public nsIInputStream {
|
|||
private:
|
||||
class Inner;
|
||||
|
||||
explicit ReadStream(Inner* aInner);
|
||||
~ReadStream();
|
||||
|
||||
// Hold a strong ref to an inner class that actually implements the
|
||||
|
@ -97,11 +96,9 @@ class ReadStream final : public nsIInputStream {
|
|||
// ReadStream guarantees it will call Close() on the inner stream.
|
||||
// This is essential for the inner stream to avoid dealing with the
|
||||
// implicit close that can happen when a stream is destroyed.
|
||||
SafeRefPtr<ReadStream::Inner> mInner;
|
||||
RefPtr<Inner> mInner;
|
||||
|
||||
public:
|
||||
explicit ReadStream(SafeRefPtr<ReadStream::Inner> aInner);
|
||||
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_DOM_CACHE_READSTREAM_IID);
|
||||
NS_DECL_THREADSAFE_ISUPPORTS
|
||||
NS_DECL_NSIINPUTSTREAM
|
||||
|
|
|
@ -10,24 +10,22 @@ namespace mozilla {
|
|||
namespace dom {
|
||||
namespace cache {
|
||||
|
||||
void StreamControl::AddReadStream(
|
||||
SafeRefPtr<ReadStream::Controllable> aReadStream) {
|
||||
void StreamControl::AddReadStream(ReadStream::Controllable* aReadStream) {
|
||||
AssertOwningThread();
|
||||
MOZ_DIAGNOSTIC_ASSERT(aReadStream);
|
||||
MOZ_ASSERT(!mReadStreamList.Contains(aReadStream));
|
||||
mReadStreamList.AppendElement(std::move(aReadStream));
|
||||
mReadStreamList.AppendElement(aReadStream);
|
||||
}
|
||||
|
||||
void StreamControl::ForgetReadStream(
|
||||
SafeRefPtr<ReadStream::Controllable> aReadStream) {
|
||||
void StreamControl::ForgetReadStream(ReadStream::Controllable* aReadStream) {
|
||||
AssertOwningThread();
|
||||
MOZ_ALWAYS_TRUE(mReadStreamList.RemoveElement(aReadStream));
|
||||
}
|
||||
|
||||
void StreamControl::NoteClosed(SafeRefPtr<ReadStream::Controllable> aReadStream,
|
||||
void StreamControl::NoteClosed(ReadStream::Controllable* aReadStream,
|
||||
const nsID& aId) {
|
||||
AssertOwningThread();
|
||||
ForgetReadStream(std::move(aReadStream));
|
||||
ForgetReadStream(aReadStream);
|
||||
NoteClosedAfterForget(aId);
|
||||
}
|
||||
|
||||
|
@ -44,9 +42,7 @@ void StreamControl::CloseReadStreams(const nsID& aId) {
|
|||
|
||||
ReadStreamList::ForwardIterator iter(mReadStreamList);
|
||||
while (iter.HasMore()) {
|
||||
// clonePtr() is necessary here, because closing the stream will cause it to
|
||||
// be removed from mReadStreamList
|
||||
SafeRefPtr<ReadStream::Controllable> stream = iter.GetNext().clonePtr();
|
||||
RefPtr<ReadStream::Controllable> stream = iter.GetNext();
|
||||
if (stream->MatchId(aId)) {
|
||||
stream->CloseStream();
|
||||
#ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
|
||||
|
@ -78,9 +74,7 @@ void StreamControl::CloseAllReadStreamsWithoutReporting() {
|
|||
|
||||
ReadStreamList::ForwardIterator iter(mReadStreamList);
|
||||
while (iter.HasMore()) {
|
||||
// clonePtr() is necessary here, because closing the stream will cause it to
|
||||
// be removed from mReadStreamList
|
||||
SafeRefPtr<ReadStream::Controllable> stream = iter.GetNext().clonePtr();
|
||||
RefPtr<ReadStream::Controllable> stream = iter.GetNext();
|
||||
// Note, we cannot trigger IPC traffic here. So use
|
||||
// CloseStreamWithoutReporting().
|
||||
stream->CloseStreamWithoutReporting();
|
||||
|
|
|
@ -42,14 +42,13 @@ class StreamControl {
|
|||
// Begin controlling the given ReadStream. This causes a strong ref to
|
||||
// be held by the control. The ReadStream must call NoteClosed() or
|
||||
// ForgetReadStream() to release this ref.
|
||||
void AddReadStream(SafeRefPtr<ReadStream::Controllable> aReadStream);
|
||||
void AddReadStream(ReadStream::Controllable* aReadStream);
|
||||
|
||||
// Forget the ReadStream without notifying the actor.
|
||||
void ForgetReadStream(SafeRefPtr<ReadStream::Controllable> aReadStream);
|
||||
void ForgetReadStream(ReadStream::Controllable* aReadStream);
|
||||
|
||||
// Forget the ReadStream and then notify the actor the stream is closed.
|
||||
void NoteClosed(SafeRefPtr<ReadStream::Controllable> aReadStream,
|
||||
const nsID& aId);
|
||||
void NoteClosed(ReadStream::Controllable* aReadStream, const nsID& aId);
|
||||
|
||||
protected:
|
||||
~StreamControl();
|
||||
|
@ -74,7 +73,7 @@ class StreamControl {
|
|||
private:
|
||||
// Hold strong references to ReadStream object. When the stream is closed
|
||||
// it should call NoteClosed() or ForgetReadStream() to release this ref.
|
||||
typedef nsTObserverArray<SafeRefPtr<ReadStream::Controllable>> ReadStreamList;
|
||||
typedef nsTObserverArray<RefPtr<ReadStream::Controllable>> ReadStreamList;
|
||||
ReadStreamList mReadStreamList;
|
||||
};
|
||||
|
||||
|
|
|
@ -7,13 +7,11 @@
|
|||
#ifndef mozilla_saferefptr_h__
|
||||
#define mozilla_saferefptr_h__
|
||||
|
||||
#include "mozilla/ArrayAlgorithm.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "mozilla/NotNull.h"
|
||||
#include "mozilla/RefCounted.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsTObserverArray.h"
|
||||
|
||||
namespace mozilla {
|
||||
template <typename T>
|
||||
|
@ -433,29 +431,6 @@ inline RefPtr<T> StrongOrRawPtr(SafeRefPtr<S>&& aPtr) {
|
|||
|
||||
} // namespace mozilla
|
||||
|
||||
template <class T>
|
||||
class nsTObserverArray<mozilla::SafeRefPtr<T>>
|
||||
: public nsAutoTObserverArray<mozilla::SafeRefPtr<T>, 0> {
|
||||
public:
|
||||
using base_type = nsAutoTObserverArray<mozilla::SafeRefPtr<T>, 0>;
|
||||
using size_type = nsTObserverArray_base::size_type;
|
||||
|
||||
// Initialization methods
|
||||
nsTObserverArray() = default;
|
||||
|
||||
// Initialize this array and pre-allocate some number of elements.
|
||||
explicit nsTObserverArray(size_type aCapacity) {
|
||||
base_type::mArray.SetCapacity(aCapacity);
|
||||
}
|
||||
|
||||
nsTObserverArray Clone() const {
|
||||
auto result = nsTObserverArray{};
|
||||
result.mArray = mozilla::TransformIntoNewArray(
|
||||
this->mArray, [](const auto& ptr) { return ptr.clonePtr(); });
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
// Use MOZ_INLINE_DECL_SAFEREFCOUNTING_INHERITED in a 'Class' derived from a
|
||||
// 'Super' class which derives from (Atomic)SafeRefCounted, and from some other
|
||||
// class using NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING.
|
||||
|
|
Загрузка…
Ссылка в новой задаче