Backed out changeset 99cce83b7e41 (bug 1636050) for assertion failures on ReadStream.cpp. CLOSED TREE

This commit is contained in:
Csoregi Natalia 2020-06-09 21:21:34 +03:00
Родитель ea9bf8c0f4
Коммит c644ee9a06
5 изменённых файлов: 40 добавлений и 76 удалений

51
dom/cache/ReadStream.cpp поставляемый
Просмотреть файл

@ -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);
}

11
dom/cache/ReadStream.h поставляемый
Просмотреть файл

@ -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

20
dom/cache/StreamControl.cpp поставляемый
Просмотреть файл

@ -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();

9
dom/cache/StreamControl.h поставляемый
Просмотреть файл

@ -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.