mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 13:21:05 +00:00
Bug 1294450 - Make AutoIPCStream favour PSendStream for large input streams. r=nfroydj
This commit is contained in:
parent
c35a0bf546
commit
ee8da66177
@ -282,6 +282,18 @@ StreamWrapper::Deserialize(const InputStreamParams& aParams,
|
||||
return false;
|
||||
}
|
||||
|
||||
Maybe<uint64_t>
|
||||
StreamWrapper::ExpectedSerializedLength()
|
||||
{
|
||||
nsCOMPtr<nsIIPCSerializableInputStream> stream =
|
||||
do_QueryInterface(mInputStream);
|
||||
|
||||
if (stream) {
|
||||
return stream->ExpectedSerializedLength();
|
||||
}
|
||||
return Nothing();
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED0(StreamWrapper::CloseRunnable,
|
||||
Runnable)
|
||||
|
||||
|
@ -1307,6 +1307,12 @@ RemoteInputStream::Deserialize(const InputStreamParams& /* aParams */,
|
||||
MOZ_CRASH("RemoteInputStream should never be deserialized");
|
||||
}
|
||||
|
||||
Maybe<uint64_t>
|
||||
RemoteInputStream::ExpectedSerializedLength()
|
||||
{
|
||||
return Nothing();
|
||||
}
|
||||
|
||||
nsIInputStream*
|
||||
RemoteInputStream::BlockAndGetInternalStream()
|
||||
{
|
||||
|
@ -20,6 +20,9 @@
|
||||
#include "mozilla/ipc/SendStream.h"
|
||||
#include "mozilla/Unused.h"
|
||||
#include "nsIAsyncInputStream.h"
|
||||
#include "nsIAsyncOutputStream.h"
|
||||
#include "nsIPipe.h"
|
||||
#include "nsStreamUtils.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace ipc {
|
||||
@ -122,17 +125,41 @@ SerializeInputStream(nsIInputStream* aStream, IPCStream& aValue, M* aManager)
|
||||
MOZ_ASSERT(aStream);
|
||||
MOZ_ASSERT(aManager);
|
||||
|
||||
// If a stream is known to be larger than 1MB, prefer sending it in chunks.
|
||||
const uint64_t kTooLargeStream = 1024 * 1024;
|
||||
|
||||
// First attempt simple stream serialization
|
||||
nsCOMPtr<nsIIPCSerializableInputStream> serializable =
|
||||
do_QueryInterface(aStream);
|
||||
if (serializable) {
|
||||
uint64_t expectedLength =
|
||||
serializable ? serializable->ExpectedSerializedLength().valueOr(0) : 0;
|
||||
if (serializable && expectedLength < kTooLargeStream) {
|
||||
SerializeInputStreamWithFdsChild(aStream, aValue, aManager);
|
||||
return;
|
||||
}
|
||||
|
||||
// As a fallback, attempt to stream the data across using a SendStream
|
||||
// actor. This will fail for blocking streams.
|
||||
// actor. For blocking streams, create a nonblocking pipe instead,
|
||||
nsCOMPtr<nsIAsyncInputStream> asyncStream = do_QueryInterface(aStream);
|
||||
if (!asyncStream) {
|
||||
const uint32_t kBufferSize = 32768; // matches SendStream buffer size.
|
||||
nsCOMPtr<nsIAsyncOutputStream> sink;
|
||||
DebugOnly<nsresult> rv = NS_NewPipe2(getter_AddRefs(asyncStream),
|
||||
getter_AddRefs(sink),
|
||||
true,
|
||||
false,
|
||||
kBufferSize,
|
||||
UINT32_MAX);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
|
||||
nsCOMPtr<nsIEventTarget> target =
|
||||
do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
|
||||
|
||||
rv = NS_AsyncCopy(aStream, sink, target, NS_ASYNCCOPY_VIA_READSEGMENTS, kBufferSize);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
}
|
||||
|
||||
MOZ_ASSERT(asyncStream);
|
||||
aValue = SendStreamChild::Create(asyncStream, aManager);
|
||||
|
||||
if (!aValue.get_PSendStreamChild()) {
|
||||
|
@ -8,6 +8,7 @@
|
||||
#define mozilla_ipc_nsIIPCSerializableInputStream_h
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "nsISupports.h"
|
||||
#include "nsTArrayForwardDeclare.h"
|
||||
|
||||
@ -38,6 +39,17 @@ public:
|
||||
virtual bool
|
||||
Deserialize(const mozilla::ipc::InputStreamParams& aParams,
|
||||
const FileDescriptorArray& aFileDescriptors) = 0;
|
||||
|
||||
// The number of bytes that are expected to be written when this
|
||||
// stream is serialized. A value of Some(N) indicates that N bytes
|
||||
// will be written to the IPC buffer, and will be used to decide
|
||||
// upon an optimal transmission mechanism. A value of Nothing
|
||||
// indicates that either serializing this stream will not require
|
||||
// serializing its contents (eg. a file-backed stream, or a stream
|
||||
// backed by an IPC actor), or the length of the stream's contents
|
||||
// cannot be determined.
|
||||
virtual mozilla::Maybe<uint64_t>
|
||||
ExpectedSerializedLength() = 0;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsIIPCSerializableInputStream,
|
||||
@ -50,7 +62,10 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsIIPCSerializableInputStream,
|
||||
\
|
||||
virtual bool \
|
||||
Deserialize(const mozilla::ipc::InputStreamParams&, \
|
||||
const FileDescriptorArray&) override;
|
||||
const FileDescriptorArray&) override; \
|
||||
\
|
||||
virtual mozilla::Maybe<uint64_t> \
|
||||
ExpectedSerializedLength() override;
|
||||
|
||||
#define NS_FORWARD_NSIIPCSERIALIZABLEINPUTSTREAM(_to) \
|
||||
virtual void \
|
||||
@ -65,6 +80,12 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsIIPCSerializableInputStream,
|
||||
const FileDescriptorArray& aFileDescriptors) override \
|
||||
{ \
|
||||
return _to Deserialize(aParams, aFileDescriptors); \
|
||||
} \
|
||||
\
|
||||
virtual mozilla::Maybe<uint64_t> \
|
||||
ExpectedSerializedLength() override \
|
||||
{ \
|
||||
return _to ExpectedSerializedLength(); \
|
||||
}
|
||||
|
||||
#define NS_FORWARD_SAFE_NSIIPCSERIALIZABLEINPUTSTREAM(_to) \
|
||||
@ -82,6 +103,12 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsIIPCSerializableInputStream,
|
||||
const FileDescriptorArray& aFileDescriptors) override \
|
||||
{ \
|
||||
return _to ? _to->Deserialize(aParams, aFileDescriptors) : false; \
|
||||
} \
|
||||
\
|
||||
virtual mozilla::Maybe<uint64_t> \
|
||||
ExpectedSerializedLength() override \
|
||||
{ \
|
||||
return _to ? _to->ExpectedSerializedLength() : Nothing(); \
|
||||
}
|
||||
|
||||
#endif // mozilla_ipc_nsIIPCSerializableInputStream_h
|
||||
|
@ -38,6 +38,9 @@ static struct {
|
||||
#endif
|
||||
|
||||
using namespace mozilla::ipc;
|
||||
using mozilla::Maybe;
|
||||
using mozilla::Nothing;
|
||||
using mozilla::Some;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsBufferedStream
|
||||
@ -541,6 +544,16 @@ nsBufferedInputStream::Deserialize(const InputStreamParams& aParams,
|
||||
return true;
|
||||
}
|
||||
|
||||
Maybe<uint64_t>
|
||||
nsBufferedInputStream::ExpectedSerializedLength()
|
||||
{
|
||||
nsCOMPtr<nsIIPCSerializableInputStream> stream = do_QueryInterface(mStream);
|
||||
if (stream) {
|
||||
return stream->ExpectedSerializedLength();
|
||||
}
|
||||
return Nothing();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsBufferedOutputStream
|
||||
|
||||
|
@ -32,6 +32,9 @@ typedef mozilla::ipc::FileDescriptor::PlatformHandleType FileHandleType;
|
||||
|
||||
using namespace mozilla::ipc;
|
||||
using mozilla::DebugOnly;
|
||||
using mozilla::Maybe;
|
||||
using mozilla::Nothing;
|
||||
using mozilla::Some;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsFileStreamBase
|
||||
@ -662,6 +665,12 @@ nsFileInputStream::Deserialize(const InputStreamParams& aParams,
|
||||
return true;
|
||||
}
|
||||
|
||||
Maybe<uint64_t>
|
||||
nsFileInputStream::ExpectedSerializedLength()
|
||||
{
|
||||
return Nothing();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsPartialFileInputStream
|
||||
|
||||
@ -860,6 +869,13 @@ nsPartialFileInputStream::Deserialize(
|
||||
return NS_SUCCEEDED(nsFileInputStream::Seek(NS_SEEK_SET, mStart));
|
||||
}
|
||||
|
||||
Maybe<uint64_t>
|
||||
nsPartialFileInputStream::ExpectedSerializedLength()
|
||||
{
|
||||
return Some(mLength);
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsPartialFileInputStream::DoPendingSeek()
|
||||
{
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "mozilla/ipc/InputStreamUtils.h"
|
||||
|
||||
using namespace mozilla::ipc;
|
||||
using mozilla::Maybe;
|
||||
|
||||
class nsMIMEInputStream : public nsIMIMEInputStream,
|
||||
public nsISeekableStream,
|
||||
@ -379,3 +380,11 @@ nsMIMEInputStream::Deserialize(const InputStreamParams& aParams,
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Maybe<uint64_t>
|
||||
nsMIMEInputStream::ExpectedSerializedLength()
|
||||
{
|
||||
nsCOMPtr<nsIIPCSerializableInputStream> serializable = do_QueryInterface(mStream);
|
||||
return serializable ? serializable->ExpectedSerializedLength() : Nothing();
|
||||
}
|
||||
|
||||
|
@ -239,3 +239,9 @@ nsTemporaryFileInputStream::Deserialize(const InputStreamParams& aParams,
|
||||
mEndPos = params.endPos();
|
||||
return true;
|
||||
}
|
||||
|
||||
Maybe<uint64_t>
|
||||
nsTemporaryFileInputStream::ExpectedSerializedLength()
|
||||
{
|
||||
return Nothing();
|
||||
}
|
||||
|
@ -29,6 +29,9 @@ using namespace mozilla;
|
||||
using namespace mozilla::ipc;
|
||||
|
||||
using mozilla::DeprecatedAbs;
|
||||
using mozilla::Maybe;
|
||||
using mozilla::Nothing;
|
||||
using mozilla::Some;
|
||||
|
||||
class nsMultiplexInputStream final
|
||||
: public nsIMultiplexInputStream
|
||||
@ -747,6 +750,29 @@ nsMultiplexInputStream::Deserialize(const InputStreamParams& aParams,
|
||||
return true;
|
||||
}
|
||||
|
||||
Maybe<uint64_t>
|
||||
nsMultiplexInputStream::ExpectedSerializedLength()
|
||||
{
|
||||
MutexAutoLock lock(mLock);
|
||||
|
||||
bool lengthValueExists = false;
|
||||
uint64_t expectedLength = 0;
|
||||
uint32_t streamCount = mStreams.Length();
|
||||
for (uint32_t index = 0; index < streamCount; index++) {
|
||||
nsCOMPtr<nsIIPCSerializableInputStream> stream = do_QueryInterface(mStreams[index]);
|
||||
if (!stream) {
|
||||
continue;
|
||||
}
|
||||
Maybe<uint64_t> length = stream->ExpectedSerializedLength();
|
||||
if (length.isNothing()) {
|
||||
continue;
|
||||
}
|
||||
lengthValueExists = true;
|
||||
expectedLength += length.value();
|
||||
}
|
||||
return lengthValueExists ? Some(expectedLength) : Nothing();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMultiplexInputStream::GetCloneable(bool* aCloneable)
|
||||
{
|
||||
|
@ -29,6 +29,8 @@
|
||||
|
||||
using mozilla::ipc::InputStreamParams;
|
||||
using mozilla::ipc::StringInputStreamParams;
|
||||
using mozilla::Maybe;
|
||||
using mozilla::Some;
|
||||
|
||||
//
|
||||
// Log module for StorageStream logging...
|
||||
@ -598,6 +600,15 @@ nsStorageInputStream::Serialize(InputStreamParams& aParams, FileDescriptorArray&
|
||||
aParams = params;
|
||||
}
|
||||
|
||||
Maybe<uint64_t>
|
||||
nsStorageInputStream::ExpectedSerializedLength()
|
||||
{
|
||||
uint64_t remaining = 0;
|
||||
DebugOnly<nsresult> rv = Available(&remaining);
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv));
|
||||
return Some(remaining);
|
||||
}
|
||||
|
||||
bool
|
||||
nsStorageInputStream::Deserialize(const InputStreamParams& aParams,
|
||||
const FileDescriptorArray&)
|
||||
|
@ -25,6 +25,8 @@
|
||||
#include "nsIIPCSerializableInputStream.h"
|
||||
|
||||
using namespace mozilla::ipc;
|
||||
using mozilla::Maybe;
|
||||
using mozilla::Some;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// nsIStringInputStream implementation
|
||||
@ -354,6 +356,12 @@ nsStringInputStream::Deserialize(const InputStreamParams& aParams,
|
||||
return true;
|
||||
}
|
||||
|
||||
Maybe<uint64_t>
|
||||
nsStringInputStream::ExpectedSerializedLength()
|
||||
{
|
||||
return Some(static_cast<uint64_t>(Length()));
|
||||
}
|
||||
|
||||
/////////
|
||||
// nsICloneableInputStream implementation
|
||||
/////////
|
||||
|
Loading…
Reference in New Issue
Block a user