mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 13:51:41 +00:00
Bug 781256 - 'Share FileDescriptors across processes in preparation for OS-level sandbox'. r=khuey+cjones.
--HG-- rename : netwerk/base/public/nsIIPCSerializable.idl => netwerk/base/public/nsIIPCSerializableObsolete.idl extra : transplant_source : %EB%18%9D%E6%B1%C6%26%A2%16%F3%85g%1A%25%B1%8E%A1%E72e
This commit is contained in:
parent
2c43844d19
commit
4b09919a18
@ -17,7 +17,8 @@
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIFileStreams.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsIIPCSerializable.h"
|
||||
#include "nsIIPCSerializableInputStream.h"
|
||||
#include "nsIIPCSerializableObsolete.h"
|
||||
#include "nsIMIMEService.h"
|
||||
#include "nsIPlatformCharset.h"
|
||||
#include "nsISeekableStream.h"
|
||||
@ -47,8 +48,9 @@ using namespace mozilla::dom;
|
||||
// stream is. We do that by passing back this class instead.
|
||||
class DataOwnerAdapter MOZ_FINAL : public nsIInputStream,
|
||||
public nsISeekableStream,
|
||||
public nsIIPCSerializable,
|
||||
public nsIClassInfo
|
||||
public nsIIPCSerializableObsolete,
|
||||
public nsIClassInfo,
|
||||
public nsIIPCSerializableInputStream
|
||||
{
|
||||
typedef nsDOMMemoryFile::DataOwner DataOwner;
|
||||
public:
|
||||
@ -65,16 +67,18 @@ public:
|
||||
|
||||
// These are optional. We use a conditional QI to keep them from being called
|
||||
// if the underlying stream doesn't QI to either interface.
|
||||
NS_FORWARD_NSIIPCSERIALIZABLE(mSerializable->)
|
||||
NS_FORWARD_NSIIPCSERIALIZABLEOBSOLETE(mSerializableObsolete->)
|
||||
NS_FORWARD_NSICLASSINFO(mClassInfo->)
|
||||
NS_FORWARD_NSIIPCSERIALIZABLEINPUTSTREAM(mSerializableInputStream->)
|
||||
|
||||
private:
|
||||
DataOwnerAdapter(DataOwner* aDataOwner,
|
||||
nsIInputStream* aStream)
|
||||
: mDataOwner(aDataOwner), mStream(aStream),
|
||||
mSeekableStream(do_QueryInterface(aStream)),
|
||||
mSerializable(do_QueryInterface(aStream)),
|
||||
mClassInfo(do_QueryInterface(aStream))
|
||||
mSerializableObsolete(do_QueryInterface(aStream)),
|
||||
mClassInfo(do_QueryInterface(aStream)),
|
||||
mSerializableInputStream(do_QueryInterface(aStream))
|
||||
{
|
||||
NS_ASSERTION(mSeekableStream, "Somebody gave us the wrong stream!");
|
||||
}
|
||||
@ -82,8 +86,9 @@ private:
|
||||
nsRefPtr<DataOwner> mDataOwner;
|
||||
nsCOMPtr<nsIInputStream> mStream;
|
||||
nsCOMPtr<nsISeekableStream> mSeekableStream;
|
||||
nsCOMPtr<nsIIPCSerializable> mSerializable;
|
||||
nsCOMPtr<nsIIPCSerializableObsolete> mSerializableObsolete;
|
||||
nsCOMPtr<nsIClassInfo> mClassInfo;
|
||||
nsCOMPtr<nsIIPCSerializableInputStream> mSerializableInputStream;
|
||||
};
|
||||
|
||||
NS_IMPL_THREADSAFE_ADDREF(DataOwnerAdapter)
|
||||
@ -92,8 +97,11 @@ NS_IMPL_THREADSAFE_RELEASE(DataOwnerAdapter)
|
||||
NS_INTERFACE_MAP_BEGIN(DataOwnerAdapter)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIInputStream)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISeekableStream)
|
||||
NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIIPCSerializable, mSerializable)
|
||||
NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIIPCSerializableObsolete,
|
||||
mSerializableObsolete)
|
||||
NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIClassInfo, mClassInfo)
|
||||
NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIIPCSerializableInputStream,
|
||||
mSerializableInputStream)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIInputStream)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
|
@ -9,7 +9,6 @@
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "IPC/IPCMessageUtils.h"
|
||||
#include "nsIIPCSerializable.h"
|
||||
#include "nsILoadContext.h"
|
||||
|
||||
/*
|
||||
|
218
dom/ipc/Blob.cpp
218
dom/ipc/Blob.cpp
@ -10,13 +10,14 @@
|
||||
|
||||
#include "nsIDOMFile.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsIIPCSerializableInputStream.h"
|
||||
#include "nsIRemoteBlob.h"
|
||||
#include "nsISeekableStream.h"
|
||||
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/Monitor.h"
|
||||
#include "mozilla/unused.h"
|
||||
#include "mozilla/net/NeckoMessageUtils.h"
|
||||
#include "mozilla/ipc/InputStreamUtils.h"
|
||||
#include "nsDOMFile.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
@ -25,6 +26,7 @@
|
||||
|
||||
using namespace mozilla::dom;
|
||||
using namespace mozilla::dom::ipc;
|
||||
using namespace mozilla::ipc;
|
||||
|
||||
namespace {
|
||||
|
||||
@ -227,10 +229,18 @@ private:
|
||||
}
|
||||
};
|
||||
|
||||
NS_IMPL_THREADSAFE_ADDREF(RemoteInputStream)
|
||||
NS_IMPL_THREADSAFE_RELEASE(RemoteInputStream)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(RemoteInputStream)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIInputStream)
|
||||
NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsISeekableStream, IsSeekableStream())
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIInputStream)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
template <ActorFlavorEnum ActorFlavor>
|
||||
class InputStreamActor : public BlobTraits<ActorFlavor>::StreamType
|
||||
{
|
||||
typedef typename BlobTraits<ActorFlavor>::StreamType::InputStream InputStream;
|
||||
nsRefPtr<RemoteInputStream> mRemoteStream;
|
||||
|
||||
public:
|
||||
@ -249,12 +259,17 @@ public:
|
||||
private:
|
||||
// This method is only called by the IPDL message machinery.
|
||||
virtual bool
|
||||
Recv__delete__(const InputStream& aStream) MOZ_OVERRIDE
|
||||
Recv__delete__(const InputStreamParams& aParams) MOZ_OVERRIDE
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mRemoteStream);
|
||||
|
||||
mRemoteStream->SetStream(aStream);
|
||||
nsCOMPtr<nsIInputStream> stream = DeserializeInputStream(aParams);
|
||||
if (!stream) {
|
||||
return false;
|
||||
}
|
||||
|
||||
mRemoteStream->SetStream(stream);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
@ -605,14 +620,10 @@ public:
|
||||
virtual void*
|
||||
GetPBlob() MOZ_OVERRIDE
|
||||
{
|
||||
return static_cast<typename ActorType::BaseType*>(mActor);
|
||||
return static_cast<typename ActorType::ProtocolType*>(mActor);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace ipc
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
||||
template <ActorFlavorEnum ActorFlavor>
|
||||
Blob<ActorFlavor>::Blob(nsIDOMBlob* aBlob)
|
||||
: mBlob(aBlob), mRemoteBlob(nullptr), mOwnsBlob(true), mBlobIsFile(false)
|
||||
@ -740,7 +751,7 @@ Blob<ActorFlavor>::SetMysteryBlobInfo(const nsString& aName,
|
||||
ToConcreteBlob(mBlob)->SetLazyData(aName, aContentType, aLength);
|
||||
|
||||
FileBlobConstructorParams params(aName, aContentType, aLength);
|
||||
return BaseType::SendResolveMystery(params);
|
||||
return ProtocolType::SendResolveMystery(params);
|
||||
}
|
||||
|
||||
template <ActorFlavorEnum ActorFlavor>
|
||||
@ -759,7 +770,7 @@ Blob<ActorFlavor>::SetMysteryBlobInfo(const nsString& aContentType,
|
||||
ToConcreteBlob(mBlob)->SetLazyData(voidString, aContentType, aLength);
|
||||
|
||||
NormalBlobConstructorParams params(aContentType, aLength);
|
||||
return BaseType::SendResolveMystery(params);
|
||||
return ProtocolType::SendResolveMystery(params);
|
||||
}
|
||||
|
||||
template <ActorFlavorEnum ActorFlavor>
|
||||
@ -809,7 +820,7 @@ Blob<ActorFlavor>::NoteDyingRemoteBlob()
|
||||
// access a dangling pointer.
|
||||
mRemoteBlob = nullptr;
|
||||
|
||||
mozilla::unused << BaseType::Send__delete__(this);
|
||||
mozilla::unused << ProtocolType::Send__delete__(this);
|
||||
}
|
||||
|
||||
template <ActorFlavorEnum ActorFlavor>
|
||||
@ -868,9 +879,9 @@ Blob<ActorFlavor>::RecvResolveMystery(const ResolveMysteryParams& aParams)
|
||||
return true;
|
||||
}
|
||||
|
||||
template <ActorFlavorEnum ActorFlavor>
|
||||
template <>
|
||||
bool
|
||||
Blob<ActorFlavor>::RecvPBlobStreamConstructor(StreamType* aActor)
|
||||
Blob<Parent>::RecvPBlobStreamConstructor(StreamType* aActor)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mBlob);
|
||||
@ -880,7 +891,55 @@ Blob<ActorFlavor>::RecvPBlobStreamConstructor(StreamType* aActor)
|
||||
nsresult rv = mBlob->GetInternalStream(getter_AddRefs(stream));
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
|
||||
return aActor->Send__delete__(aActor, stream.get());
|
||||
nsCOMPtr<nsIIPCSerializableInputStream> serializable =
|
||||
do_QueryInterface(stream);
|
||||
if (!serializable) {
|
||||
MOZ_ASSERT(false, "Must be serializable!");
|
||||
return false;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIEventTarget> target =
|
||||
do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
|
||||
NS_ENSURE_TRUE(target, false);
|
||||
|
||||
nsRefPtr<BaseType::OpenStreamRunnable> runnable =
|
||||
new BaseType::OpenStreamRunnable(this, aActor, stream, serializable,
|
||||
target);
|
||||
|
||||
rv = target->Dispatch(runnable, NS_DISPATCH_NORMAL);
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
|
||||
nsRevocableEventPtr<BaseType::OpenStreamRunnable>* arrayMember =
|
||||
mOpenStreamRunnables.AppendElement();
|
||||
*arrayMember = runnable;
|
||||
return true;
|
||||
}
|
||||
|
||||
template <>
|
||||
bool
|
||||
Blob<Child>::RecvPBlobStreamConstructor(StreamType* aActor)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mBlob);
|
||||
MOZ_ASSERT(!mRemoteBlob);
|
||||
|
||||
nsCOMPtr<nsIInputStream> stream;
|
||||
nsresult rv = mBlob->GetInternalStream(getter_AddRefs(stream));
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
|
||||
nsCOMPtr<nsIIPCSerializableInputStream> serializable =
|
||||
do_QueryInterface(stream);
|
||||
if (!serializable) {
|
||||
MOZ_ASSERT(false, "Must be serializable!");
|
||||
return false;
|
||||
}
|
||||
|
||||
InputStreamParams params;
|
||||
serializable->Serialize(params);
|
||||
|
||||
MOZ_ASSERT(params.type() != InputStreamParams::T__None);
|
||||
|
||||
return aActor->Send__delete__(aActor, params);
|
||||
}
|
||||
|
||||
template <ActorFlavorEnum ActorFlavor>
|
||||
@ -910,18 +969,127 @@ template <ActorFlavorEnum ActorFlavor>
|
||||
NS_IMPL_QUERY_INTERFACE_INHERITED1(RemoteBlob<ActorFlavor>, nsDOMFile,
|
||||
nsIRemoteBlob)
|
||||
|
||||
NS_IMPL_THREADSAFE_ADDREF(RemoteInputStream)
|
||||
NS_IMPL_THREADSAFE_RELEASE(RemoteInputStream)
|
||||
void
|
||||
BlobTraits<Parent>::BaseType::NoteRunnableCompleted(
|
||||
BlobTraits<Parent>::BaseType::OpenStreamRunnable* aRunnable)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(RemoteInputStream)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIInputStream)
|
||||
NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsISeekableStream, IsSeekableStream())
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIInputStream)
|
||||
NS_INTERFACE_MAP_END
|
||||
for (PRUint32 index = 0; index < mOpenStreamRunnables.Length(); index++) {
|
||||
nsRevocableEventPtr<BaseType::OpenStreamRunnable>& runnable =
|
||||
mOpenStreamRunnables[index];
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
namespace ipc {
|
||||
if (runnable.get() == aRunnable) {
|
||||
runnable.Forget();
|
||||
mOpenStreamRunnables.RemoveElementAt(index);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
MOZ_NOT_REACHED("Runnable not in our array!");
|
||||
}
|
||||
|
||||
BlobTraits<Parent>::BaseType::
|
||||
OpenStreamRunnable::OpenStreamRunnable(
|
||||
BlobTraits<Parent>::BaseType* aOwner,
|
||||
BlobTraits<Parent>::StreamType* aActor,
|
||||
nsIInputStream* aStream,
|
||||
nsIIPCSerializableInputStream* aSerializable,
|
||||
nsIEventTarget* aTarget)
|
||||
: mOwner(aOwner), mActor(aActor), mStream(aStream),
|
||||
mSerializable(aSerializable), mTarget(aTarget), mRevoked(false),
|
||||
mClosing(false)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aOwner);
|
||||
MOZ_ASSERT(aActor);
|
||||
MOZ_ASSERT(aStream);
|
||||
MOZ_ASSERT(aSerializable);
|
||||
MOZ_ASSERT(aTarget);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
BlobTraits<Parent>::BaseType::OpenStreamRunnable::Run()
|
||||
{
|
||||
MOZ_ASSERT(mStream);
|
||||
|
||||
nsresult rv;
|
||||
|
||||
if (NS_IsMainThread()) {
|
||||
MOZ_ASSERT(mTarget);
|
||||
MOZ_ASSERT(!mClosing);
|
||||
|
||||
if (mRevoked) {
|
||||
MOZ_ASSERT(!mOwner);
|
||||
MOZ_ASSERT(!mActor);
|
||||
}
|
||||
else {
|
||||
MOZ_ASSERT(mOwner);
|
||||
MOZ_ASSERT(mActor);
|
||||
|
||||
nsCOMPtr<nsIIPCSerializableInputStream> serializable;
|
||||
mSerializable.swap(serializable);
|
||||
|
||||
InputStreamParams params;
|
||||
serializable->Serialize(params);
|
||||
|
||||
MOZ_ASSERT(params.type() != InputStreamParams::T__None);
|
||||
|
||||
unused << mActor->Send__delete__(mActor, params);
|
||||
|
||||
mOwner->NoteRunnableCompleted(this);
|
||||
|
||||
#ifdef DEBUG
|
||||
mOwner = nullptr;
|
||||
mActor = nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
mClosing = true;
|
||||
|
||||
nsCOMPtr<nsIEventTarget> target;
|
||||
mTarget.swap(target);
|
||||
|
||||
rv = target->Dispatch(this, NS_DISPATCH_NORMAL);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (!mClosing) {
|
||||
// To force the stream open we call Available(). We don't actually care how
|
||||
// much data is available.
|
||||
PRUint64 available;
|
||||
if (NS_FAILED(mStream->Available(&available))) {
|
||||
NS_WARNING("Available failed on this stream!");
|
||||
}
|
||||
|
||||
rv = NS_DispatchToMainThread(this, NS_DISPATCH_NORMAL);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Going to always release here.
|
||||
nsCOMPtr<nsIInputStream> stream;
|
||||
mStream.swap(stream);
|
||||
|
||||
rv = stream->Close();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
void
|
||||
BlobTraits<Parent>::BaseType::OpenStreamRunnable::Revoke()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
mOwner = nullptr;
|
||||
mActor = nullptr;
|
||||
mRevoked = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Explicit instantiation of both classes.
|
||||
template class Blob<Parent>;
|
||||
|
@ -12,12 +12,16 @@
|
||||
#include "mozilla/dom/PBlobParent.h"
|
||||
#include "mozilla/dom/PBlobStreamChild.h"
|
||||
#include "mozilla/dom/PBlobStreamParent.h"
|
||||
#include "mozilla/dom/PContentChild.h"
|
||||
#include "mozilla/dom/PContentParent.h"
|
||||
#include "mozilla/dom/PContent.h"
|
||||
|
||||
#include "nsAutoPtr.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
class nsIDOMBlob;
|
||||
class nsIIPCSerializableInputStream;
|
||||
class nsIInputStream;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
@ -36,17 +40,92 @@ struct BlobTraits
|
||||
template <>
|
||||
struct BlobTraits<Parent>
|
||||
{
|
||||
typedef mozilla::dom::PBlobParent BaseType;
|
||||
typedef mozilla::dom::PBlobParent ProtocolType;
|
||||
typedef mozilla::dom::PBlobStreamParent StreamType;
|
||||
typedef mozilla::dom::PContentParent ManagerType;
|
||||
|
||||
// BaseType on the parent side is a bit more complicated than for the child
|
||||
// side. In the case of nsIInputStreams backed by files we need to ensure that
|
||||
// the files are actually opened and closed on a background thread before we
|
||||
// can send their file handles across to the child. The child process could
|
||||
// crash during this process so we need to make sure we cancel the intended
|
||||
// response in such a case. We do that by holding an array of
|
||||
// nsRevocableEventPtr. If the child crashes then this actor will be destroyed
|
||||
// and the nsRevocableEventPtr destructor will cancel any stream events that
|
||||
// are currently in flight.
|
||||
class BaseType : public ProtocolType
|
||||
{
|
||||
protected:
|
||||
BaseType()
|
||||
{ }
|
||||
|
||||
virtual ~BaseType()
|
||||
{ }
|
||||
|
||||
// Each instance of this class will be dispatched to the network stream
|
||||
// thread pool to run the first time where it will open the file input
|
||||
// stream. It will then dispatch itself back to the main thread to send the
|
||||
// child process its response (assuming that the child has not crashed). The
|
||||
// runnable will then dispatch itself to the thread pool again in order to
|
||||
// close the file input stream.
|
||||
class OpenStreamRunnable : public nsRunnable
|
||||
{
|
||||
friend class nsRevocableEventPtr<OpenStreamRunnable>;
|
||||
public:
|
||||
NS_DECL_NSIRUNNABLE
|
||||
|
||||
OpenStreamRunnable(BaseType* aOwner, StreamType* aActor,
|
||||
nsIInputStream* aStream,
|
||||
nsIIPCSerializableInputStream* aSerializable,
|
||||
nsIEventTarget* aTarget);
|
||||
|
||||
private:
|
||||
#ifdef DEBUG
|
||||
void
|
||||
Revoke();
|
||||
#else
|
||||
void
|
||||
Revoke()
|
||||
{
|
||||
mRevoked = true;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Only safe to access these two pointers if mRevoked is false!
|
||||
BaseType* mOwner;
|
||||
StreamType* mActor;
|
||||
|
||||
nsCOMPtr<nsIInputStream> mStream;
|
||||
nsCOMPtr<nsIIPCSerializableInputStream> mSerializable;
|
||||
nsCOMPtr<nsIEventTarget> mTarget;
|
||||
|
||||
bool mRevoked;
|
||||
bool mClosing;
|
||||
};
|
||||
|
||||
friend class OpenStreamRunnable;
|
||||
|
||||
void
|
||||
NoteRunnableCompleted(OpenStreamRunnable* aRunnable);
|
||||
|
||||
nsTArray<nsRevocableEventPtr<OpenStreamRunnable> > mOpenStreamRunnables;
|
||||
};
|
||||
};
|
||||
|
||||
template <>
|
||||
struct BlobTraits<Child>
|
||||
{
|
||||
typedef mozilla::dom::PBlobChild BaseType;
|
||||
typedef mozilla::dom::PBlobChild ProtocolType;
|
||||
typedef mozilla::dom::PBlobStreamChild StreamType;
|
||||
typedef mozilla::dom::PContentChild ManagerType;
|
||||
|
||||
class BaseType : public ProtocolType
|
||||
{
|
||||
protected:
|
||||
BaseType()
|
||||
{ }
|
||||
|
||||
virtual ~BaseType()
|
||||
{ }
|
||||
};
|
||||
};
|
||||
|
||||
template <ActorFlavorEnum>
|
||||
@ -58,9 +137,9 @@ class Blob : public BlobTraits<ActorFlavor>::BaseType
|
||||
friend class RemoteBlob<ActorFlavor>;
|
||||
|
||||
public:
|
||||
typedef typename BlobTraits<ActorFlavor>::BaseType BaseType;
|
||||
typedef typename BlobTraits<ActorFlavor>::ProtocolType ProtocolType;
|
||||
typedef typename BlobTraits<ActorFlavor>::StreamType StreamType;
|
||||
typedef typename BlobTraits<ActorFlavor>::ManagerType ManagerType;
|
||||
typedef typename BlobTraits<ActorFlavor>::BaseType BaseType;
|
||||
typedef RemoteBlob<ActorFlavor> RemoteBlobType;
|
||||
typedef mozilla::ipc::IProtocolManager<
|
||||
mozilla::ipc::RPCChannel::RPCListener>::ActorDestroyReason
|
||||
|
@ -3,10 +3,7 @@
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
include protocol PBlob;
|
||||
|
||||
include "mozilla/net/NeckoMessageUtils.h";
|
||||
|
||||
using IPC::InputStream;
|
||||
include IPCSerializableParams;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
@ -16,7 +13,7 @@ protocol PBlobStream
|
||||
manager PBlob;
|
||||
|
||||
both:
|
||||
__delete__(InputStream stream);
|
||||
__delete__(InputStreamParams params);
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
@ -14,7 +14,6 @@ include "mozilla/dom/TabMessageUtils.h";
|
||||
|
||||
using NPError;
|
||||
using NPNVariable;
|
||||
using base::FileDescriptor;
|
||||
using mozilla::dom::NativeThreadId;
|
||||
using mac_plugin_interposing::NSCursorInfo;
|
||||
using nsID;
|
||||
|
@ -1850,10 +1850,10 @@ PluginModuleChild::AnswerNP_Initialize(const uint32_t& aFlags, NPError* _retval)
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_X11
|
||||
// Send the parent a dup of our X socket, to act as a proxy
|
||||
// reference for our X resources
|
||||
// Send the parent our X socket to act as a proxy reference for our X
|
||||
// resources.
|
||||
int xSocketFd = ConnectionNumber(DefaultXDisplay());
|
||||
SendBackUpXResources(FileDescriptor(xSocketFd, false/*don't close*/));
|
||||
SendBackUpXResources(FileDescriptor(xSocketFd));
|
||||
#endif
|
||||
|
||||
#if defined(OS_LINUX)
|
||||
|
@ -689,9 +689,8 @@ PluginModuleParent::RecvBackUpXResources(const FileDescriptor& aXSocketFd)
|
||||
#else
|
||||
NS_ABORT_IF_FALSE(0 > mPluginXSocketFdDup.get(),
|
||||
"Already backed up X resources??");
|
||||
int fd = aXSocketFd.fd; // Copy to discard |const| qualifier
|
||||
mPluginXSocketFdDup.forget();
|
||||
mPluginXSocketFdDup.reset(fd);
|
||||
mPluginXSocketFdDup.reset(aXSocketFd.PlatformHandle());
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
65
ipc/glue/FileDescriptor.cpp
Normal file
65
ipc/glue/FileDescriptor.cpp
Normal file
@ -0,0 +1,65 @@
|
||||
/* 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 "FileDescriptor.h"
|
||||
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "nsDebug.h"
|
||||
|
||||
#ifdef XP_WIN
|
||||
#include <windows.h>
|
||||
#define INVALID_HANDLE INVALID_HANDLE_VALUE
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#define INVALID_HANDLE -1
|
||||
#endif
|
||||
|
||||
using mozilla::ipc::FileDescriptor;
|
||||
|
||||
FileDescriptor::FileDescriptor()
|
||||
: mHandle(INVALID_HANDLE)
|
||||
{ }
|
||||
|
||||
FileDescriptor::PickleType
|
||||
FileDescriptor::ShareTo(const FileDescriptor::IPDLPrivate&,
|
||||
FileDescriptor::ProcessHandle aOtherProcess) const
|
||||
{
|
||||
#ifdef XP_WIN
|
||||
if (mHandle == INVALID_HANDLE) {
|
||||
return INVALID_HANDLE;
|
||||
}
|
||||
|
||||
PlatformHandleType newHandle;
|
||||
if (!DuplicateHandle(GetCurrentProcess(), mHandle, aOtherProcess, &newHandle,
|
||||
0, FALSE, DUPLICATE_SAME_ACCESS)) {
|
||||
NS_WARNING("Failed to duplicate file handle!");
|
||||
return INVALID_HANDLE;
|
||||
}
|
||||
|
||||
return newHandle;
|
||||
#else // XP_WIN
|
||||
if (mHandle == INVALID_HANDLE) {
|
||||
return base::FileDescriptor();
|
||||
}
|
||||
|
||||
PlatformHandleType newHandle = dup(mHandle);
|
||||
if (newHandle < 0) {
|
||||
NS_WARNING("Failed to duplicate file descriptor!");
|
||||
return base::FileDescriptor();
|
||||
}
|
||||
|
||||
// This file descriptor must be closed once the caller is done using it, so
|
||||
// pass true here for the 'auto_close' argument.
|
||||
return base::FileDescriptor(newHandle, true);
|
||||
#endif
|
||||
|
||||
MOZ_NOT_REACHED("Must not get here!");
|
||||
return PickleType();
|
||||
}
|
||||
|
||||
bool
|
||||
FileDescriptor::IsValid() const
|
||||
{
|
||||
return mHandle != INVALID_HANDLE;
|
||||
}
|
95
ipc/glue/FileDescriptor.h
Normal file
95
ipc/glue/FileDescriptor.h
Normal file
@ -0,0 +1,95 @@
|
||||
/* 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/. */
|
||||
|
||||
#ifndef mozilla_ipc_FileDescriptor_h
|
||||
#define mozilla_ipc_FileDescriptor_h
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "base/process.h"
|
||||
#include "nscore.h"
|
||||
|
||||
#ifdef XP_WIN
|
||||
// Need the HANDLE typedef.
|
||||
#include <winnt.h>
|
||||
#else
|
||||
#include "base/file_descriptor_posix.h"
|
||||
#endif
|
||||
|
||||
namespace mozilla {
|
||||
namespace ipc {
|
||||
|
||||
// This class is used by IPDL to share file descriptors across processes. When
|
||||
// sending a FileDescriptor IPDL will first duplicate a platform-specific file
|
||||
// handle type ('PlatformHandleType') into a handle that is valid in the other
|
||||
// process. Then IPDL will convert the duplicated handle into a type suitable
|
||||
// for pickling ('PickleType') and then send that through the IPC pipe. In the
|
||||
// receiving process the pickled data is converted into a platform-specific file
|
||||
// handle and then returned to the receiver.
|
||||
//
|
||||
// To use this class add 'FileDescriptor' as an argument in the IPDL protocol
|
||||
// and then pass a file descriptor from C++ to the Call/Send method. The
|
||||
// Answer/Recv method will receive a FileDescriptor& on which PlatformHandle()
|
||||
// can be called to return the platform file handle.
|
||||
class FileDescriptor
|
||||
{
|
||||
public:
|
||||
typedef base::ProcessHandle ProcessHandle;
|
||||
|
||||
#ifdef XP_WIN
|
||||
typedef HANDLE PlatformHandleType;
|
||||
typedef HANDLE PickleType;
|
||||
#else
|
||||
typedef int PlatformHandleType;
|
||||
typedef base::FileDescriptor PickleType;
|
||||
#endif
|
||||
|
||||
// This should only ever be created by IPDL.
|
||||
struct IPDLPrivate
|
||||
{};
|
||||
|
||||
FileDescriptor();
|
||||
|
||||
FileDescriptor(PlatformHandleType aHandle)
|
||||
: mHandle(aHandle)
|
||||
{ }
|
||||
|
||||
FileDescriptor(const IPDLPrivate&, const PickleType& aPickle)
|
||||
#ifdef XP_WIN
|
||||
: mHandle(aPickle)
|
||||
#else
|
||||
: mHandle(aPickle.fd)
|
||||
#endif
|
||||
{ }
|
||||
|
||||
// Performs platform-specific actions to duplicate mHandle in the other
|
||||
// process (e.g. dup() on POSIX, DuplicateHandle() on Windows). Returns a
|
||||
// pickled value that can be passed to the other process via IPC.
|
||||
PickleType
|
||||
ShareTo(const IPDLPrivate&, ProcessHandle aOtherProcess) const;
|
||||
|
||||
// Tests mHandle against a well-known invalid platform-specific file handle
|
||||
// (e.g. -1 on POSIX, INVALID_HANDLE_VALUE on Windows).
|
||||
bool
|
||||
IsValid() const;
|
||||
|
||||
PlatformHandleType
|
||||
PlatformHandle() const
|
||||
{
|
||||
return mHandle;
|
||||
}
|
||||
|
||||
bool
|
||||
operator==(const FileDescriptor& aOther) const
|
||||
{
|
||||
return mHandle == aOther.mHandle;
|
||||
}
|
||||
|
||||
private:
|
||||
PlatformHandleType mHandle;
|
||||
};
|
||||
|
||||
} // namespace ipc
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_ipc_FileDescriptor_h
|
44
ipc/glue/IPCSerializableParams.ipdlh
Normal file
44
ipc/glue/IPCSerializableParams.ipdlh
Normal file
@ -0,0 +1,44 @@
|
||||
/* 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/. */
|
||||
|
||||
namespace mozilla {
|
||||
namespace ipc {
|
||||
|
||||
struct StringInputStreamParams
|
||||
{
|
||||
nsCString data;
|
||||
};
|
||||
|
||||
struct FileInputStreamParams
|
||||
{
|
||||
FileDescriptor file;
|
||||
int32_t behaviorFlags;
|
||||
int32_t ioFlags;
|
||||
};
|
||||
|
||||
struct PartialFileInputStreamParams
|
||||
{
|
||||
FileInputStreamParams fileStreamParams;
|
||||
uint64_t begin;
|
||||
uint64_t length;
|
||||
};
|
||||
|
||||
struct MultiplexInputStreamParams
|
||||
{
|
||||
InputStreamParams[] streams;
|
||||
uint32_t currentStream;
|
||||
nsresult status;
|
||||
bool startedReadingCurrent;
|
||||
};
|
||||
|
||||
union InputStreamParams
|
||||
{
|
||||
StringInputStreamParams;
|
||||
FileInputStreamParams;
|
||||
PartialFileInputStreamParams;
|
||||
MultiplexInputStreamParams;
|
||||
};
|
||||
|
||||
} // namespace ipc
|
||||
} // namespace mozilla
|
79
ipc/glue/InputStreamUtils.cpp
Normal file
79
ipc/glue/InputStreamUtils.cpp
Normal file
@ -0,0 +1,79 @@
|
||||
/* 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 "InputStreamUtils.h"
|
||||
|
||||
#include "nsIIPCSerializableInputStream.h"
|
||||
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
#include "nsDebug.h"
|
||||
#include "nsID.h"
|
||||
#include "nsMultiplexInputStream.h"
|
||||
#include "nsNetCID.h"
|
||||
#include "nsStringStream.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
using namespace mozilla::ipc;
|
||||
|
||||
namespace {
|
||||
|
||||
NS_DEFINE_CID(kStringInputStreamCID, NS_STRINGINPUTSTREAM_CID);
|
||||
NS_DEFINE_CID(kFileInputStreamCID, NS_LOCALFILEINPUTSTREAM_CID);
|
||||
NS_DEFINE_CID(kPartialFileInputStreamCID, NS_PARTIALLOCALFILEINPUTSTREAM_CID);
|
||||
NS_DEFINE_CID(kMultiplexInputStreamCID, NS_MULTIPLEXINPUTSTREAM_CID);
|
||||
|
||||
} // anonymous namespace
|
||||
|
||||
namespace mozilla {
|
||||
namespace ipc {
|
||||
|
||||
already_AddRefed<nsIInputStream>
|
||||
DeserializeInputStream(const InputStreamParams& aParams)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
nsCOMPtr<nsIIPCSerializableInputStream> serializable;
|
||||
|
||||
switch (aParams.type()) {
|
||||
case InputStreamParams::T__None:
|
||||
NS_WARNING("This union has no type!");
|
||||
return nullptr;
|
||||
|
||||
case InputStreamParams::TStringInputStreamParams:
|
||||
serializable = do_CreateInstance(kStringInputStreamCID);
|
||||
break;
|
||||
|
||||
case InputStreamParams::TFileInputStreamParams:
|
||||
serializable = do_CreateInstance(kFileInputStreamCID);
|
||||
break;
|
||||
|
||||
case InputStreamParams::TPartialFileInputStreamParams:
|
||||
serializable = do_CreateInstance(kPartialFileInputStreamCID);
|
||||
break;
|
||||
|
||||
case InputStreamParams::TMultiplexInputStreamParams:
|
||||
serializable = do_CreateInstance(kMultiplexInputStreamCID);
|
||||
break;
|
||||
|
||||
default:
|
||||
NS_WARNING("Unknown params!");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(serializable);
|
||||
|
||||
if (!serializable->Deserialize(aParams)) {
|
||||
NS_WARNING("Deserialize failed!");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIInputStream> stream = do_QueryInterface(serializable);
|
||||
MOZ_ASSERT(stream);
|
||||
|
||||
return stream.forget();
|
||||
}
|
||||
|
||||
} // namespace ipc
|
||||
} // namespace mozilla
|
21
ipc/glue/InputStreamUtils.h
Normal file
21
ipc/glue/InputStreamUtils.h
Normal file
@ -0,0 +1,21 @@
|
||||
/* 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/. */
|
||||
|
||||
#ifndef mozilla_ipc_InputStreamUtils_h
|
||||
#define mozilla_ipc_InputStreamUtils_h
|
||||
|
||||
#include "mozilla/ipc/IPCSerializableParams.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIInputStream.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace ipc {
|
||||
|
||||
already_AddRefed<nsIInputStream>
|
||||
DeserializeInputStream(const InputStreamParams& aParams);
|
||||
|
||||
} // namespace ipc
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_ipc_InputStreamUtils_h
|
@ -25,7 +25,9 @@ EXPORTS_mozilla/ipc = \
|
||||
AsyncChannel.h \
|
||||
BrowserProcessSubThread.h \
|
||||
CrossProcessMutex.h \
|
||||
FileDescriptor.h \
|
||||
GeckoChildProcessHost.h \
|
||||
InputStreamUtils.h \
|
||||
IOThreadChild.h \
|
||||
ProcessChild.h \
|
||||
ProtocolUtils.h \
|
||||
@ -40,6 +42,8 @@ EXPORTS_mozilla/ipc = \
|
||||
Transport.h \
|
||||
$(NULL)
|
||||
|
||||
EXPORTS = nsIIPCSerializableInputStream.h
|
||||
|
||||
ifeq ($(OS_ARCH),WINNT) #{
|
||||
EXPORTS_mozilla/ipc += \
|
||||
Transport_win.h \
|
||||
@ -63,7 +67,9 @@ endif #}
|
||||
CPPSRCS += \
|
||||
AsyncChannel.cpp \
|
||||
BrowserProcessSubThread.cpp \
|
||||
FileDescriptor.cpp \
|
||||
GeckoChildProcessHost.cpp \
|
||||
InputStreamUtils.cpp \
|
||||
MessagePump.cpp \
|
||||
ProcessChild.cpp \
|
||||
ProtocolUtils.cpp \
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "prenv.h"
|
||||
|
||||
#include "IPCMessageStart.h"
|
||||
#include "mozilla/ipc/FileDescriptor.h"
|
||||
#include "mozilla/ipc/Shmem.h"
|
||||
#include "mozilla/ipc/Transport.h"
|
||||
|
||||
|
5
ipc/glue/ipdl.mk
Normal file
5
ipc/glue/ipdl.mk
Normal file
@ -0,0 +1,5 @@
|
||||
# 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/.
|
||||
|
||||
IPDLSRCS = IPCSerializableParams.ipdlh
|
57
ipc/glue/nsIIPCSerializableInputStream.h
Normal file
57
ipc/glue/nsIIPCSerializableInputStream.h
Normal file
@ -0,0 +1,57 @@
|
||||
/* 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/. */
|
||||
|
||||
#ifndef mozilla_ipc_nsIIPCSerializableInputStream_h
|
||||
#define mozilla_ipc_nsIIPCSerializableInputStream_h
|
||||
|
||||
#include "nsISupports.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace ipc {
|
||||
class InputStreamParams;
|
||||
}
|
||||
}
|
||||
|
||||
#define NS_IIPCSERIALIZABLEINPUTSTREAM_IID \
|
||||
{0x1f56a3f8, 0xc413, 0x4274, {0x88, 0xe6, 0x68, 0x50, 0x9d, 0xf8, 0x85, 0x2d}}
|
||||
|
||||
class NS_NO_VTABLE nsIIPCSerializableInputStream : public nsISupports
|
||||
{
|
||||
public:
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_IIPCSERIALIZABLEINPUTSTREAM_IID)
|
||||
|
||||
virtual void
|
||||
Serialize(mozilla::ipc::InputStreamParams& aParams) = 0;
|
||||
|
||||
virtual bool
|
||||
Deserialize(const mozilla::ipc::InputStreamParams& aParams) = 0;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsIIPCSerializableInputStream,
|
||||
NS_IIPCSERIALIZABLEINPUTSTREAM_IID)
|
||||
|
||||
#define NS_DECL_NSIIPCSERIALIZABLEINPUTSTREAM \
|
||||
virtual void \
|
||||
Serialize(mozilla::ipc::InputStreamParams&) MOZ_OVERRIDE; \
|
||||
virtual bool \
|
||||
Deserialize(const mozilla::ipc::InputStreamParams&) MOZ_OVERRIDE;
|
||||
|
||||
#define NS_FORWARD_NSIIPCSERIALIZABLEINPUTSTREAM(_to) \
|
||||
virtual void \
|
||||
Serialize(mozilla::ipc::InputStreamParams& aParams) MOZ_OVERRIDE \
|
||||
{ _to Serialize(aParams); } \
|
||||
virtual bool \
|
||||
Deserialize(const mozilla::ipc::InputStreamParams& aParams) MOZ_OVERRIDE \
|
||||
{ return _to Deserialize(aParams); }
|
||||
|
||||
#define NS_FORWARD_SAFE_NSIIPCSERIALIZABLEINPUTSTREAM(_to) \
|
||||
virtual void \
|
||||
Serialize(mozilla::ipc::InputStreamParams& aParams) MOZ_OVERRIDE \
|
||||
{ if (_to) { _to->Serialize(aParams); } } \
|
||||
virtual bool \
|
||||
Deserialize(const mozilla::ipc::InputStreamParams& aParams) MOZ_OVERRIDE \
|
||||
{ if (_to) { return _to->Deserialize(aParams); } return false; }
|
||||
|
||||
#endif // mozilla_ipc_nsIIPCSerializableInputStream_h
|
@ -32,6 +32,7 @@ IPDLDIRS = \
|
||||
dom/src/storage \
|
||||
gfx/layers/ipc \
|
||||
hal/sandbox \
|
||||
ipc/glue \
|
||||
ipc/testshell \
|
||||
js/ipc \
|
||||
layout/ipc \
|
||||
|
@ -48,6 +48,7 @@ Types = (
|
||||
'nsString',
|
||||
'nsCString',
|
||||
'mozilla::ipc::Shmem',
|
||||
'mozilla::ipc::FileDescriptor',
|
||||
|
||||
# quasi-stdint types used by "public" Gecko headers
|
||||
'int8',
|
||||
|
@ -233,7 +233,6 @@ def _shmemRevokeRights(shmemexpr):
|
||||
def _lookupShmem(idexpr):
|
||||
return ExprCall(ExprVar('LookupSharedMemory'), args=[ idexpr ])
|
||||
|
||||
|
||||
def _makeForwardDeclForQClass(clsname, quals):
|
||||
fd = ForwardDecl(clsname, cls=1)
|
||||
if 0 == len(quals):
|
||||
@ -492,6 +491,9 @@ class _ConvertToCxxType(TypeVisitor):
|
||||
def visitShmemType(self, s):
|
||||
return Type(self.typename(s))
|
||||
|
||||
def visitFDType(self, s):
|
||||
return Type(self.typename(s))
|
||||
|
||||
def visitProtocolType(self, p): assert 0
|
||||
def visitMessageType(self, m): assert 0
|
||||
def visitVoidType(self, v): assert 0
|
||||
@ -668,6 +670,8 @@ class _StructField(_CompoundTypeComponent):
|
||||
refexpr = self.refExpr(thisexpr)
|
||||
if 'Shmem' == self.ipdltype.name():
|
||||
refexpr = ExprCast(refexpr, Type('Shmem', ref=1), const=1)
|
||||
if 'FileDescriptor' == self.ipdltype.name():
|
||||
refexpr = ExprCast(refexpr, Type('FileDescriptor', ref=1), const=1)
|
||||
return refexpr
|
||||
|
||||
def argVar(self):
|
||||
@ -826,6 +830,8 @@ IPDL union type."""
|
||||
# sigh
|
||||
if 'Shmem' == self.ipdltype.name():
|
||||
v = ExprCast(v, Type('Shmem', ref=1), const=1)
|
||||
if 'FileDescriptor' == self.ipdltype.name():
|
||||
v = ExprCast(v, Type('FileDescriptor', ref=1), const=1)
|
||||
return v
|
||||
|
||||
##--------------------------------------------------
|
||||
@ -990,7 +996,6 @@ def _subtreeUsesShmem(p):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
class Protocol(ipdl.ast.Protocol):
|
||||
def cxxTypedefs(self):
|
||||
return self.decl.cxxtypedefs
|
||||
@ -1867,6 +1872,11 @@ stmt. Some types generate both kinds.'''
|
||||
self.visited.add(s)
|
||||
self.maybeTypedef('mozilla::ipc::Shmem', 'Shmem')
|
||||
|
||||
def visitFDType(self, s):
|
||||
if s in self.visited: return
|
||||
self.visited.add(s)
|
||||
self.maybeTypedef('mozilla::ipc::FileDescriptor', 'FileDescriptor')
|
||||
|
||||
def visitVoidType(self, v): assert 0
|
||||
def visitMessageType(self, v): assert 0
|
||||
def visitProtocolType(self, v): assert 0
|
||||
@ -3379,11 +3389,11 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
|
||||
p = self.protocol
|
||||
routedvar = ExprVar('aRouted')
|
||||
idvar = ExprVar('aId')
|
||||
shmemvar = ExprVar('aShmem')
|
||||
shmemvar = ExprVar('shmem')
|
||||
rawvar = ExprVar('segment')
|
||||
sizevar = ExprVar('aSize')
|
||||
typevar = ExprVar('type')
|
||||
unsafevar = ExprVar('unsafe')
|
||||
typevar = ExprVar('aType')
|
||||
unsafevar = ExprVar('aUnsafe')
|
||||
listenertype = Type('ChannelListener', ptr=1)
|
||||
|
||||
register = MethodDefn(MethodDecl(
|
||||
@ -3978,8 +3988,9 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
|
||||
# pickling for IPDL types
|
||||
specialtypes = set()
|
||||
class findSpecialTypes(TypeVisitor):
|
||||
def visitActorType(self, a): specialtypes.add(a)
|
||||
def visitShmemType(self, s): specialtypes.add(s)
|
||||
def visitActorType(self, a): specialtypes.add(a)
|
||||
def visitShmemType(self, s): specialtypes.add(s)
|
||||
def visitFDType(self, s): specialtypes.add(s)
|
||||
def visitStructType(self, s):
|
||||
specialtypes.add(s)
|
||||
return TypeVisitor.visitStructType(self, s)
|
||||
@ -4006,6 +4017,7 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
|
||||
if t.isActor(): self.implementActorPickling(t)
|
||||
elif t.isArray(): self.implementSpecialArrayPickling(t)
|
||||
elif t.isShmem(): self.implementShmemPickling(t)
|
||||
elif t.isFD(): self.implementFDPickling(t)
|
||||
elif t.isStruct(): self.implementStructPickling(t)
|
||||
elif t.isUnion(): self.implementUnionPickling(t)
|
||||
else:
|
||||
@ -4225,6 +4237,57 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
|
||||
|
||||
self.cls.addstmts([ write, Whitespace.NL, read, Whitespace.NL ])
|
||||
|
||||
def implementFDPickling(self, fdtype):
|
||||
msgvar = self.msgvar
|
||||
itervar = self.itervar
|
||||
var = self.var
|
||||
tmpvar = ExprVar('fd')
|
||||
picklevar = ExprVar('pfd')
|
||||
intype = _cxxConstRefType(fdtype, self.side)
|
||||
outtype = _cxxPtrToType(fdtype, self.side)
|
||||
|
||||
def _fdType():
|
||||
return Type('FileDescriptor')
|
||||
|
||||
def _fdPickleType():
|
||||
return Type('FileDescriptor::PickleType')
|
||||
|
||||
def _fdBackstagePass():
|
||||
return ExprCall(ExprVar('FileDescriptor::IPDLPrivate'))
|
||||
|
||||
write = MethodDefn(self.writeMethodDecl(intype, var))
|
||||
write.addstmts([
|
||||
StmtDecl(Decl(_fdPickleType(), picklevar.name),
|
||||
init=ExprCall(ExprSelect(var, '.', 'ShareTo'),
|
||||
args=[ _fdBackstagePass(),
|
||||
self.protocol.callOtherProcess() ])),
|
||||
StmtExpr(ExprCall(ExprVar('IPC::WriteParam'),
|
||||
args=[ msgvar, picklevar ])),
|
||||
])
|
||||
|
||||
read = MethodDefn(self.readMethodDecl(outtype, var))
|
||||
ifread = StmtIf(ExprNot(ExprCall(ExprVar('IPC::ReadParam'),
|
||||
args=[ msgvar, itervar,
|
||||
ExprAddrOf(picklevar) ])))
|
||||
ifread.addifstmt(StmtReturn.FALSE)
|
||||
|
||||
ifnvalid = StmtIf(ExprNot(ExprCall(ExprSelect(tmpvar, '.', 'IsValid'))))
|
||||
ifnvalid.addifstmt(StmtReturn.FALSE)
|
||||
|
||||
read.addstmts([
|
||||
StmtDecl(Decl(_fdPickleType(), picklevar.name)),
|
||||
ifread,
|
||||
Whitespace.NL,
|
||||
StmtDecl(Decl(_fdType(), tmpvar.name),
|
||||
init=ExprCall(ExprVar('FileDescriptor'),
|
||||
args=[ _fdBackstagePass(), picklevar ])),
|
||||
ifnvalid,
|
||||
Whitespace.NL,
|
||||
StmtExpr(ExprAssn(ExprDeref(var), tmpvar)),
|
||||
StmtReturn.TRUE
|
||||
])
|
||||
|
||||
self.cls.addstmts([ write, Whitespace.NL, read, Whitespace.NL ])
|
||||
|
||||
def implementStructPickling(self, structtype):
|
||||
msgvar = self.msgvar
|
||||
|
@ -89,6 +89,9 @@ class TypeVisitor:
|
||||
def visitShmemChmodType(self, c, *args):
|
||||
c.shmem.accept(self)
|
||||
|
||||
def visitFDType(self, s, *args):
|
||||
pass
|
||||
|
||||
|
||||
class Type:
|
||||
def __cmp__(self, o):
|
||||
@ -196,6 +199,7 @@ class IPDLType(Type):
|
||||
def isCompound(self): return False
|
||||
def isShmem(self): return False
|
||||
def isChmod(self): return False
|
||||
def isFD(self): return False
|
||||
|
||||
def isAsync(self): return self.sendSemantics is ASYNC
|
||||
def isSync(self): return self.sendSemantics is SYNC
|
||||
@ -417,6 +421,16 @@ class ShmemType(IPDLType):
|
||||
def fullname(self):
|
||||
return str(self.qname)
|
||||
|
||||
class FDType(IPDLType):
|
||||
def __init__(self, qname):
|
||||
self.qname = qname
|
||||
def isFD(self): return True
|
||||
|
||||
def name(self):
|
||||
return self.qname.baseid
|
||||
def fullname(self):
|
||||
return str(self.qname)
|
||||
|
||||
def iteractortypes(t, visited=None):
|
||||
"""Iterate over any actor(s) buried in |type|."""
|
||||
if visited is None:
|
||||
@ -452,6 +466,17 @@ def hasshmem(type):
|
||||
return True
|
||||
return False
|
||||
|
||||
def hasfd(type):
|
||||
"""Return true iff |type| is fd or has it buried within."""
|
||||
class found: pass
|
||||
class findFD(TypeVisitor):
|
||||
def visitFDType(self, s): raise found()
|
||||
try:
|
||||
type.accept(findFD())
|
||||
except found:
|
||||
return True
|
||||
return False
|
||||
|
||||
##--------------------
|
||||
_builtinloc = Loc('<builtin>', 0)
|
||||
def makeBuiltinUsing(tname):
|
||||
@ -775,6 +800,8 @@ class GatherDecls(TcheckVisitor):
|
||||
fullname = None
|
||||
if fullname == 'mozilla::ipc::Shmem':
|
||||
ipdltype = ShmemType(using.type.spec)
|
||||
elif fullname == 'mozilla::ipc::FileDescriptor':
|
||||
ipdltype = FDType(using.type.spec)
|
||||
else:
|
||||
ipdltype = ImportedCxxType(using.type.spec)
|
||||
using.decl = self.declare(
|
||||
|
@ -52,7 +52,7 @@ XPIDLSRCS = \
|
||||
nsIInputStreamPump.idl \
|
||||
nsIInputStreamChannel.idl \
|
||||
nsIIOService2.idl \
|
||||
nsIIPCSerializable.idl \
|
||||
nsIIPCSerializableObsolete.idl \
|
||||
nsIMIMEInputStream.idl \
|
||||
nsINetAddr.idl \
|
||||
nsINetworkLinkService.idl \
|
||||
|
@ -17,7 +17,7 @@ class Message;
|
||||
[ptr] native Iterator(void*);
|
||||
|
||||
[noscript, uuid(1f605ac7-666b-471f-9864-1a21a95f11c4)]
|
||||
interface nsIIPCSerializable : nsISupports
|
||||
interface nsIIPCSerializableObsolete : nsISupports
|
||||
{
|
||||
[notxpcom] boolean read(in ConstMessage msg, in Iterator iter);
|
||||
[notxpcom] void write(in Message msg);
|
@ -252,7 +252,7 @@ NS_INTERFACE_MAP_BEGIN(nsBufferedInputStream)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIInputStream)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIBufferedInputStream)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIStreamBufferAccess)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIIPCSerializable)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIIPCSerializableObsolete)
|
||||
NS_IMPL_QUERY_CLASSINFO(nsBufferedInputStream)
|
||||
NS_INTERFACE_MAP_END_INHERITING(nsBufferedStream)
|
||||
|
||||
@ -261,7 +261,7 @@ NS_IMPL_CI_INTERFACE_GETTER5(nsBufferedInputStream,
|
||||
nsIBufferedInputStream,
|
||||
nsISeekableStream,
|
||||
nsIStreamBufferAccess,
|
||||
nsIIPCSerializable)
|
||||
nsIIPCSerializableObsolete)
|
||||
|
||||
nsresult
|
||||
nsBufferedInputStream::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
|
||||
|
@ -13,7 +13,7 @@
|
||||
#include "nsISeekableStream.h"
|
||||
#include "nsIStreamBufferAccess.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIIPCSerializable.h"
|
||||
#include "nsIIPCSerializableObsolete.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@ -60,14 +60,14 @@ protected:
|
||||
class nsBufferedInputStream : public nsBufferedStream,
|
||||
public nsIBufferedInputStream,
|
||||
public nsIStreamBufferAccess,
|
||||
public nsIIPCSerializable
|
||||
public nsIIPCSerializableObsolete
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSIINPUTSTREAM
|
||||
NS_DECL_NSIBUFFEREDINPUTSTREAM
|
||||
NS_DECL_NSISTREAMBUFFERACCESS
|
||||
NS_DECL_NSIIPCSERIALIZABLE
|
||||
NS_DECL_NSIIPCSERIALIZABLEOBSOLETE
|
||||
|
||||
nsBufferedInputStream() : nsBufferedStream() {}
|
||||
virtual ~nsBufferedInputStream() {}
|
||||
|
@ -28,9 +28,14 @@
|
||||
#include "nsReadLine.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsIClassInfoImpl.h"
|
||||
#include "mozilla/ipc/IPCSerializableParams.h"
|
||||
|
||||
#define NS_NO_INPUT_BUFFERING 1 // see http://bugzilla.mozilla.org/show_bug.cgi?id=41067
|
||||
|
||||
typedef mozilla::ipc::FileDescriptor::PlatformHandleType FileHandleType;
|
||||
|
||||
using namespace mozilla::ipc;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsFileStreamBase
|
||||
|
||||
@ -286,12 +291,16 @@ nsFileStreamBase::CleanUpOpen()
|
||||
nsresult
|
||||
nsFileStreamBase::DoOpen()
|
||||
{
|
||||
NS_PRECONDITION(mOpenParams.localFile, "Must have a file to open");
|
||||
NS_ASSERTION(!mFD, "Already have a file descriptor!");
|
||||
NS_ASSERTION(mOpenParams.localFile, "Must have a file to open");
|
||||
|
||||
PRFileDesc* fd;
|
||||
nsresult rv = mOpenParams.localFile->OpenNSPRFileDesc(mOpenParams.ioFlags, mOpenParams.perm, &fd);
|
||||
nsresult rv = mOpenParams.localFile->OpenNSPRFileDesc(mOpenParams.ioFlags,
|
||||
mOpenParams.perm,
|
||||
&fd);
|
||||
CleanUpOpen();
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
mFD = fd;
|
||||
|
||||
return NS_OK;
|
||||
@ -320,16 +329,16 @@ NS_INTERFACE_MAP_BEGIN(nsFileInputStream)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIInputStream)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIFileInputStream)
|
||||
NS_INTERFACE_MAP_ENTRY(nsILineInputStream)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIIPCSerializable)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIIPCSerializableObsolete)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIIPCSerializableInputStream)
|
||||
NS_IMPL_QUERY_CLASSINFO(nsFileInputStream)
|
||||
NS_INTERFACE_MAP_END_INHERITING(nsFileStreamBase)
|
||||
|
||||
NS_IMPL_CI_INTERFACE_GETTER5(nsFileInputStream,
|
||||
NS_IMPL_CI_INTERFACE_GETTER4(nsFileInputStream,
|
||||
nsIInputStream,
|
||||
nsIFileInputStream,
|
||||
nsISeekableStream,
|
||||
nsILineInputStream,
|
||||
nsIIPCSerializable)
|
||||
nsILineInputStream)
|
||||
|
||||
nsresult
|
||||
nsFileInputStream::Create(nsISupports *aOuter, REFNSIID aIID, void **aResult)
|
||||
@ -505,6 +514,76 @@ nsFileInputStream::Write(IPC::Message *aMsg)
|
||||
WriteParam(aMsg, mBehaviorFlags);
|
||||
}
|
||||
|
||||
void
|
||||
nsFileInputStream::Serialize(InputStreamParams& aParams)
|
||||
{
|
||||
FileInputStreamParams params;
|
||||
|
||||
if (mFD) {
|
||||
FileHandleType fd = FileHandleType(PR_FileDesc2NativeHandle(mFD));
|
||||
NS_ASSERTION(fd, "This should never be null!");
|
||||
|
||||
params.file() = FileDescriptor(fd);
|
||||
NS_ASSERTION(params.file().IsValid(),
|
||||
"Sending an invalid file descriptor!");
|
||||
} else {
|
||||
NS_WARNING("This file has not been opened (or could not be opened). "
|
||||
"Sending an invalid file descriptor to the other process!");
|
||||
}
|
||||
|
||||
PRInt32 behaviorFlags = mBehaviorFlags;
|
||||
|
||||
// The other process shouldn't close when it reads the end because it will
|
||||
// not be able to reopen the file later.
|
||||
behaviorFlags &= ~nsIFileInputStream::CLOSE_ON_EOF;
|
||||
|
||||
// The other process will not be able to reopen the file so transferring
|
||||
// this flag is meaningless.
|
||||
behaviorFlags &= ~nsIFileInputStream::REOPEN_ON_REWIND;
|
||||
|
||||
// The other process is going to have an open file descriptor automatically
|
||||
// so transferring this flag is meaningless.
|
||||
behaviorFlags &= ~nsIFileInputStream::DEFER_OPEN;
|
||||
|
||||
params.behaviorFlags() = behaviorFlags;
|
||||
params.ioFlags() = mIOFlags;
|
||||
|
||||
aParams = params;
|
||||
}
|
||||
|
||||
bool
|
||||
nsFileInputStream::Deserialize(const InputStreamParams& aParams)
|
||||
{
|
||||
NS_ASSERTION(!mFD, "Already have a file descriptor?!");
|
||||
NS_ASSERTION(!mDeferredOpen, "Deferring open?!");
|
||||
NS_ASSERTION(!mFile, "Should never have a file here!");
|
||||
NS_ASSERTION(!mPerm, "This should always be 0!");
|
||||
|
||||
if (aParams.type() != InputStreamParams::TFileInputStreamParams) {
|
||||
NS_WARNING("Received unknown parameters from the other process!");
|
||||
return false;
|
||||
}
|
||||
|
||||
const FileInputStreamParams& params = aParams.get_FileInputStreamParams();
|
||||
|
||||
const FileDescriptor& fd = params.file();
|
||||
NS_WARN_IF_FALSE(fd.IsValid(), "Received an invalid file descriptor!");
|
||||
|
||||
if (fd.IsValid()) {
|
||||
PRFileDesc* fileDesc = PR_ImportFile(PROsfd(fd.PlatformHandle()));
|
||||
if (!fileDesc) {
|
||||
NS_WARNING("Failed to import file handle!");
|
||||
return false;
|
||||
}
|
||||
mFD = fileDesc;
|
||||
}
|
||||
|
||||
mBehaviorFlags = params.behaviorFlags();
|
||||
mIOFlags = params.ioFlags();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsPartialFileInputStream
|
||||
|
||||
@ -520,16 +599,16 @@ NS_INTERFACE_MAP_BEGIN(nsPartialFileInputStream)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIInputStream)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIPartialFileInputStream)
|
||||
NS_INTERFACE_MAP_ENTRY(nsILineInputStream)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIIPCSerializable)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIIPCSerializableObsolete)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIIPCSerializableInputStream)
|
||||
NS_IMPL_QUERY_CLASSINFO(nsPartialFileInputStream)
|
||||
NS_INTERFACE_MAP_END_INHERITING(nsFileStreamBase)
|
||||
|
||||
NS_IMPL_CI_INTERFACE_GETTER5(nsPartialFileInputStream,
|
||||
NS_IMPL_CI_INTERFACE_GETTER4(nsPartialFileInputStream,
|
||||
nsIInputStream,
|
||||
nsIPartialFileInputStream,
|
||||
nsISeekableStream,
|
||||
nsILineInputStream,
|
||||
nsIIPCSerializable)
|
||||
nsILineInputStream)
|
||||
|
||||
nsresult
|
||||
nsPartialFileInputStream::Create(nsISupports *aOuter, REFNSIID aIID,
|
||||
@ -680,6 +759,64 @@ nsPartialFileInputStream::Write(IPC::Message *aMsg)
|
||||
nsFileInputStream::Write(aMsg);
|
||||
}
|
||||
|
||||
void
|
||||
nsPartialFileInputStream::Serialize(InputStreamParams& aParams)
|
||||
{
|
||||
// Serialize the base class first.
|
||||
InputStreamParams fileParams;
|
||||
nsFileInputStream::Serialize(fileParams);
|
||||
|
||||
if (fileParams.type() != InputStreamParams::TFileInputStreamParams) {
|
||||
NS_ERROR("Base class serialize failed!");
|
||||
return;
|
||||
}
|
||||
|
||||
PartialFileInputStreamParams params;
|
||||
|
||||
params.fileStreamParams() = fileParams.get_FileInputStreamParams();
|
||||
params.begin() = mStart;
|
||||
params.length() = mLength;
|
||||
|
||||
aParams = params;
|
||||
}
|
||||
|
||||
bool
|
||||
nsPartialFileInputStream::Deserialize(const InputStreamParams& aParams)
|
||||
{
|
||||
NS_ASSERTION(!mFD, "Already have a file descriptor?!");
|
||||
NS_ASSERTION(!mStart, "Already have a start?!");
|
||||
NS_ASSERTION(!mLength, "Already have a length?!");
|
||||
NS_ASSERTION(!mPosition, "Already have a position?!");
|
||||
|
||||
if (aParams.type() != InputStreamParams::TPartialFileInputStreamParams) {
|
||||
NS_ERROR("Received unknown parameters from the other process!");
|
||||
return false;
|
||||
}
|
||||
|
||||
const PartialFileInputStreamParams& params =
|
||||
aParams.get_PartialFileInputStreamParams();
|
||||
|
||||
// Deserialize the base class first.
|
||||
InputStreamParams fileParams(params.fileStreamParams());
|
||||
if (!nsFileInputStream::Deserialize(fileParams)) {
|
||||
NS_ERROR("Base class deserialize failed!");
|
||||
return false;
|
||||
}
|
||||
|
||||
NS_ASSERTION(mFD, "Must have a file descriptor now!");
|
||||
|
||||
mStart = params.begin();
|
||||
mLength = params.length();
|
||||
mPosition = 0;
|
||||
|
||||
if (!mStart) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// XXX This is so broken. Main thread IO alert.
|
||||
return NS_SUCCEEDED(nsFileInputStream::Seek(NS_SEEK_SET, mStart));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsFileOutputStream
|
||||
|
||||
|
@ -17,7 +17,8 @@
|
||||
#include "nsCOMPtr.h"
|
||||
#include "prlog.h"
|
||||
#include "prio.h"
|
||||
#include "nsIIPCSerializable.h"
|
||||
#include "nsIIPCSerializableInputStream.h"
|
||||
#include "nsIIPCSerializableObsolete.h"
|
||||
|
||||
template<class CharType> class nsLineBuffer;
|
||||
|
||||
@ -102,13 +103,15 @@ protected:
|
||||
class nsFileInputStream : public nsFileStreamBase,
|
||||
public nsIFileInputStream,
|
||||
public nsILineInputStream,
|
||||
public nsIIPCSerializable
|
||||
public nsIIPCSerializableObsolete,
|
||||
public nsIIPCSerializableInputStream
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSIFILEINPUTSTREAM
|
||||
NS_DECL_NSILINEINPUTSTREAM
|
||||
NS_DECL_NSIIPCSERIALIZABLE
|
||||
NS_DECL_NSIIPCSERIALIZABLEOBSOLETE
|
||||
NS_DECL_NSIIPCSERIALIZABLEINPUTSTREAM
|
||||
|
||||
NS_IMETHOD Close();
|
||||
NS_IMETHOD Available(PRUint64* _retval)
|
||||
@ -131,9 +134,11 @@ public:
|
||||
NS_IMETHOD Seek(PRInt32 aWhence, PRInt64 aOffset);
|
||||
|
||||
nsFileInputStream()
|
||||
: mIOFlags(0), mPerm(0)
|
||||
{
|
||||
mLineBuffer = nullptr;
|
||||
}
|
||||
|
||||
virtual ~nsFileInputStream()
|
||||
{
|
||||
Close();
|
||||
@ -179,7 +184,12 @@ public:
|
||||
using nsFileInputStream::Init;
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSIPARTIALFILEINPUTSTREAM
|
||||
NS_DECL_NSIIPCSERIALIZABLE
|
||||
NS_DECL_NSIIPCSERIALIZABLEOBSOLETE
|
||||
NS_DECL_NSIIPCSERIALIZABLEINPUTSTREAM
|
||||
|
||||
nsPartialFileInputStream()
|
||||
: mStart(0), mLength(0), mPosition(0)
|
||||
{ }
|
||||
|
||||
NS_IMETHOD Tell(PRInt64 *aResult);
|
||||
NS_IMETHOD Available(PRUint64 *aResult);
|
||||
|
@ -19,12 +19,12 @@
|
||||
#include "nsIStringStream.h"
|
||||
#include "nsString.h"
|
||||
#include "nsMIMEInputStream.h"
|
||||
#include "nsIIPCSerializable.h"
|
||||
#include "nsIIPCSerializableObsolete.h"
|
||||
#include "nsIClassInfoImpl.h"
|
||||
|
||||
class nsMIMEInputStream : public nsIMIMEInputStream,
|
||||
public nsISeekableStream,
|
||||
public nsIIPCSerializable
|
||||
public nsIIPCSerializableObsolete
|
||||
{
|
||||
public:
|
||||
nsMIMEInputStream();
|
||||
@ -34,7 +34,7 @@ public:
|
||||
NS_DECL_NSIINPUTSTREAM
|
||||
NS_DECL_NSIMIMEINPUTSTREAM
|
||||
NS_DECL_NSISEEKABLESTREAM
|
||||
NS_DECL_NSIIPCSERIALIZABLE
|
||||
NS_DECL_NSIIPCSERIALIZABLEOBSOLETE
|
||||
|
||||
NS_METHOD Init();
|
||||
|
||||
@ -73,12 +73,12 @@ NS_IMPL_QUERY_INTERFACE4_CI(nsMIMEInputStream,
|
||||
nsIMIMEInputStream,
|
||||
nsIInputStream,
|
||||
nsISeekableStream,
|
||||
nsIIPCSerializable)
|
||||
nsIIPCSerializableObsolete)
|
||||
NS_IMPL_CI_INTERFACE_GETTER4(nsMIMEInputStream,
|
||||
nsIMIMEInputStream,
|
||||
nsIInputStream,
|
||||
nsISeekableStream,
|
||||
nsIIPCSerializable)
|
||||
nsIIPCSerializableObsolete)
|
||||
|
||||
nsMIMEInputStream::nsMIMEInputStream() : mAddContentLength(false),
|
||||
mStartedReading(false)
|
||||
|
@ -55,7 +55,7 @@ nsSimpleNestedURI::Write(nsIObjectOutputStream* aStream)
|
||||
return rv;
|
||||
}
|
||||
|
||||
// nsIIPCSerializable
|
||||
// nsIIPCSerializableObsolete
|
||||
|
||||
bool
|
||||
nsSimpleNestedURI::Read(const IPC::Message *aMsg, void **aIter)
|
||||
|
@ -36,7 +36,7 @@ public:
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSINESTEDURI
|
||||
NS_DECL_NSIIPCSERIALIZABLE
|
||||
NS_DECL_NSIIPCSERIALIZABLEOBSOLETE
|
||||
|
||||
// Overrides for various methods nsSimpleURI implements follow.
|
||||
|
||||
|
@ -41,7 +41,8 @@ nsSimpleURI::~nsSimpleURI()
|
||||
NS_IMPL_ADDREF(nsSimpleURI)
|
||||
NS_IMPL_RELEASE(nsSimpleURI)
|
||||
NS_INTERFACE_TABLE_HEAD(nsSimpleURI)
|
||||
NS_INTERFACE_TABLE5(nsSimpleURI, nsIURI, nsISerializable, nsIIPCSerializable, nsIClassInfo, nsIMutable)
|
||||
NS_INTERFACE_TABLE5(nsSimpleURI, nsIURI, nsISerializable,
|
||||
nsIIPCSerializableObsolete, nsIClassInfo, nsIMutable)
|
||||
NS_INTERFACE_TABLE_TO_MAP_SEGUE
|
||||
if (aIID.Equals(kThisSimpleURIImplementationCID))
|
||||
foundInterface = static_cast<nsIURI*>(this);
|
||||
@ -117,7 +118,7 @@ nsSimpleURI::Write(nsIObjectOutputStream* aStream)
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsIIPCSerializable methods:
|
||||
// nsIIPCSerializableObsolete methods:
|
||||
|
||||
bool
|
||||
nsSimpleURI::Read(const IPC::Message *aMsg, void **aIter)
|
||||
|
@ -9,7 +9,7 @@
|
||||
#include "nsIURL.h"
|
||||
#include "nsAgg.h"
|
||||
#include "nsISerializable.h"
|
||||
#include "nsIIPCSerializable.h"
|
||||
#include "nsIIPCSerializableObsolete.h"
|
||||
#include "nsString.h"
|
||||
#include "nsIClassInfo.h"
|
||||
#include "nsIMutable.h"
|
||||
@ -25,7 +25,7 @@
|
||||
|
||||
class nsSimpleURI : public nsIURI,
|
||||
public nsISerializable,
|
||||
public nsIIPCSerializable,
|
||||
public nsIIPCSerializableObsolete,
|
||||
public nsIClassInfo,
|
||||
public nsIMutable,
|
||||
public nsISizeOf
|
||||
@ -34,7 +34,7 @@ public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIURI
|
||||
NS_DECL_NSISERIALIZABLE
|
||||
NS_DECL_NSIIPCSERIALIZABLE
|
||||
NS_DECL_NSIIPCSERIALIZABLEOBSOLETE
|
||||
NS_DECL_NSICLASSINFO
|
||||
NS_DECL_NSIMUTABLE
|
||||
|
||||
|
@ -937,7 +937,7 @@ NS_INTERFACE_MAP_BEGIN(nsStandardURL)
|
||||
NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIFileURL, mSupportsFileURL)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIStandardURL)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISerializable)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIIPCSerializable)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIIPCSerializableObsolete)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIClassInfo)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIMutable)
|
||||
// see nsStandardURL::Equals
|
||||
@ -2876,7 +2876,7 @@ nsStandardURL::Write(nsIObjectOutputStream *stream)
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// nsStandardURL::nsIIPCSerializable
|
||||
// nsStandardURL::nsIIPCSerializableObsolete
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
bool
|
||||
|
@ -10,7 +10,7 @@
|
||||
#include "nsDependentString.h"
|
||||
#include "nsDependentSubstring.h"
|
||||
#include "nsISerializable.h"
|
||||
#include "nsIIPCSerializable.h"
|
||||
#include "nsIIPCSerializableObsolete.h"
|
||||
#include "nsIFileURL.h"
|
||||
#include "nsIStandardURL.h"
|
||||
#include "nsIFile.h"
|
||||
@ -42,7 +42,7 @@ class nsIPrefBranch;
|
||||
class nsStandardURL : public nsIFileURL
|
||||
, public nsIStandardURL
|
||||
, public nsISerializable
|
||||
, public nsIIPCSerializable
|
||||
, public nsIIPCSerializableObsolete
|
||||
, public nsIClassInfo
|
||||
, public nsISizeOf
|
||||
{
|
||||
@ -53,7 +53,7 @@ public:
|
||||
NS_DECL_NSIFILEURL
|
||||
NS_DECL_NSISTANDARDURL
|
||||
NS_DECL_NSISERIALIZABLE
|
||||
NS_DECL_NSIIPCSERIALIZABLE
|
||||
NS_DECL_NSIIPCSERIALIZABLEOBSOLETE
|
||||
NS_DECL_NSICLASSINFO
|
||||
NS_DECL_NSIMUTABLE
|
||||
|
||||
|
@ -9,7 +9,7 @@
|
||||
#include "IPC/IPCMessageUtils.h"
|
||||
#include "nsStringGlue.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsIIPCSerializable.h"
|
||||
#include "nsIIPCSerializableObsolete.h"
|
||||
#include "nsIClassInfo.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
#include "nsNetUtil.h"
|
||||
@ -51,7 +51,8 @@ struct ParamTraits<URI>
|
||||
if (isNull)
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsIIPCSerializable> serializable = do_QueryInterface(aParam.mURI);
|
||||
nsCOMPtr<nsIIPCSerializableObsolete> serializable =
|
||||
do_QueryInterface(aParam.mURI);
|
||||
if (!serializable) {
|
||||
nsCString scheme;
|
||||
aParam.mURI->GetScheme(scheme);
|
||||
@ -120,7 +121,7 @@ struct ParamTraits<URI>
|
||||
nsCOMPtr<nsIURI> uri = do_CreateInstance(cid);
|
||||
if (!uri)
|
||||
return false;
|
||||
nsCOMPtr<nsIIPCSerializable> serializable = do_QueryInterface(uri);
|
||||
nsCOMPtr<nsIIPCSerializableObsolete> serializable = do_QueryInterface(uri);
|
||||
if (!serializable || !serializable->Read(aMsg, aIter))
|
||||
return false;
|
||||
|
||||
@ -170,12 +171,14 @@ struct ParamTraits<InputStream>
|
||||
if (isNull)
|
||||
return;
|
||||
|
||||
nsCOMPtr<nsIIPCSerializable> serializable = do_QueryInterface(aParam.mStream);
|
||||
nsCOMPtr<nsIIPCSerializableObsolete> serializable =
|
||||
do_QueryInterface(aParam.mStream);
|
||||
bool isSerializable = !!serializable;
|
||||
WriteParam(aMsg, isSerializable);
|
||||
|
||||
if (!serializable) {
|
||||
NS_WARNING("nsIInputStream implementation doesn't support nsIIPCSerializable; falling back to copying data");
|
||||
NS_WARNING("nsIInputStream implementation doesn't support "
|
||||
"nsIIPCSerializableObsolete; falling back to copying data");
|
||||
|
||||
nsCString streamString;
|
||||
PRUint64 bytes;
|
||||
@ -241,7 +244,8 @@ struct ParamTraits<InputStream>
|
||||
stream = do_CreateInstance(cid);
|
||||
if (!stream)
|
||||
return false;
|
||||
nsCOMPtr<nsIIPCSerializable> serializable = do_QueryInterface(stream);
|
||||
nsCOMPtr<nsIIPCSerializableObsolete> serializable =
|
||||
do_QueryInterface(stream);
|
||||
if (!serializable || !serializable->Read(aMsg, aIter))
|
||||
return false;
|
||||
}
|
||||
|
@ -292,7 +292,7 @@ nsNestedAboutURI::Write(nsIObjectOutputStream* aStream)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// nsIIPCSerializable
|
||||
// nsIIPCSerializableObsolete
|
||||
bool
|
||||
nsNestedAboutURI::Read(const IPC::Message *aMsg, void **aIter)
|
||||
{
|
||||
|
@ -45,7 +45,7 @@ private:
|
||||
// Class to allow us to propagate the base URI to about:blank correctly
|
||||
class nsNestedAboutURI : public nsSimpleNestedURI {
|
||||
public:
|
||||
NS_DECL_NSIIPCSERIALIZABLE
|
||||
NS_DECL_NSIIPCSERIALIZABLEOBSOLETE
|
||||
|
||||
nsNestedAboutURI(nsIURI* aInnerURI, nsIURI* aBaseURI)
|
||||
: nsSimpleNestedURI(aInnerURI)
|
||||
|
@ -15,7 +15,6 @@
|
||||
#include "nsHttpHeaderArray.h"
|
||||
#include "nsHttpResponseHead.h"
|
||||
|
||||
#include "nsIIPCSerializable.h"
|
||||
#include "nsIClassInfo.h"
|
||||
#include "nsNetUtil.h"
|
||||
|
||||
|
@ -17,12 +17,18 @@
|
||||
#include "nsISeekableStream.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsCOMArray.h"
|
||||
#include "nsIIPCSerializable.h"
|
||||
#include "nsIIPCSerializableObsolete.h"
|
||||
#include "nsIClassInfoImpl.h"
|
||||
#include "nsIIPCSerializableInputStream.h"
|
||||
#include "mozilla/ipc/InputStreamUtils.h"
|
||||
#include "mozilla/ipc/IPCSerializableParams.h"
|
||||
|
||||
using namespace mozilla::ipc;
|
||||
|
||||
class nsMultiplexInputStream MOZ_FINAL : public nsIMultiplexInputStream,
|
||||
public nsISeekableStream,
|
||||
public nsIIPCSerializable
|
||||
public nsIIPCSerializableObsolete,
|
||||
public nsIIPCSerializableInputStream
|
||||
{
|
||||
public:
|
||||
nsMultiplexInputStream();
|
||||
@ -31,7 +37,8 @@ public:
|
||||
NS_DECL_NSIINPUTSTREAM
|
||||
NS_DECL_NSIMULTIPLEXINPUTSTREAM
|
||||
NS_DECL_NSISEEKABLESTREAM
|
||||
NS_DECL_NSIIPCSERIALIZABLE
|
||||
NS_DECL_NSIIPCSERIALIZABLEOBSOLETE
|
||||
NS_DECL_NSIIPCSERIALIZABLEINPUTSTREAM
|
||||
|
||||
private:
|
||||
~nsMultiplexInputStream() {}
|
||||
@ -60,16 +67,16 @@ NS_IMPL_THREADSAFE_RELEASE(nsMultiplexInputStream)
|
||||
NS_IMPL_CLASSINFO(nsMultiplexInputStream, NULL, nsIClassInfo::THREADSAFE,
|
||||
NS_MULTIPLEXINPUTSTREAM_CID)
|
||||
|
||||
NS_IMPL_QUERY_INTERFACE4_CI(nsMultiplexInputStream,
|
||||
NS_IMPL_QUERY_INTERFACE5_CI(nsMultiplexInputStream,
|
||||
nsIMultiplexInputStream,
|
||||
nsIInputStream,
|
||||
nsISeekableStream,
|
||||
nsIIPCSerializable)
|
||||
NS_IMPL_CI_INTERFACE_GETTER4(nsMultiplexInputStream,
|
||||
nsIIPCSerializableObsolete,
|
||||
nsIIPCSerializableInputStream)
|
||||
NS_IMPL_CI_INTERFACE_GETTER3(nsMultiplexInputStream,
|
||||
nsIMultiplexInputStream,
|
||||
nsIInputStream,
|
||||
nsISeekableStream,
|
||||
nsIIPCSerializable)
|
||||
nsISeekableStream)
|
||||
|
||||
nsMultiplexInputStream::nsMultiplexInputStream()
|
||||
: mCurrentStream(0),
|
||||
@ -447,3 +454,75 @@ nsMultiplexInputStream::Write(IPC::Message *aMsg)
|
||||
WriteParam(aMsg, mStartedReadingCurrent);
|
||||
WriteParam(aMsg, mStatus);
|
||||
}
|
||||
|
||||
void
|
||||
nsMultiplexInputStream::Serialize(InputStreamParams& aParams)
|
||||
{
|
||||
MultiplexInputStreamParams params;
|
||||
|
||||
PRUint32 streamCount = mStreams.Count();
|
||||
|
||||
if (streamCount) {
|
||||
InfallibleTArray<InputStreamParams>& streams = params.streams();
|
||||
|
||||
streams.SetCapacity(streamCount);
|
||||
for (PRUint32 index = 0; index < streamCount; index++) {
|
||||
nsCOMPtr<nsIIPCSerializableInputStream> serializable =
|
||||
do_QueryInterface(mStreams.ObjectAt(index));
|
||||
NS_ASSERTION(serializable, "Child stream isn't serializable!");
|
||||
|
||||
if (serializable) {
|
||||
InputStreamParams childStreamParams;
|
||||
serializable->Serialize(childStreamParams);
|
||||
|
||||
NS_ASSERTION(childStreamParams.type() !=
|
||||
InputStreamParams::T__None,
|
||||
"Serialize failed!");
|
||||
|
||||
streams.AppendElement(childStreamParams);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
params.currentStream() = mCurrentStream;
|
||||
params.status() = mStatus;
|
||||
params.startedReadingCurrent() = mStartedReadingCurrent;
|
||||
|
||||
aParams = params;
|
||||
}
|
||||
|
||||
bool
|
||||
nsMultiplexInputStream::Deserialize(const InputStreamParams& aParams)
|
||||
{
|
||||
if (aParams.type() !=
|
||||
InputStreamParams::TMultiplexInputStreamParams) {
|
||||
NS_ERROR("Received unknown parameters from the other process!");
|
||||
return false;
|
||||
}
|
||||
|
||||
const MultiplexInputStreamParams& params =
|
||||
aParams.get_MultiplexInputStreamParams();
|
||||
|
||||
const InfallibleTArray<InputStreamParams>& streams = params.streams();
|
||||
|
||||
PRUint32 streamCount = streams.Length();
|
||||
for (PRUint32 index = 0; index < streamCount; index++) {
|
||||
nsCOMPtr<nsIInputStream> stream =
|
||||
DeserializeInputStream(streams[index]);
|
||||
if (!stream) {
|
||||
NS_WARNING("Deserialize failed!");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (NS_FAILED(AppendStream(stream))) {
|
||||
NS_WARNING("AppendStream failed!");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
mCurrentStream = params.currentStream();
|
||||
mStatus = params.status();
|
||||
mStartedReadingCurrent = params.startedReadingCurrent();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -19,8 +19,12 @@
|
||||
#include "prerror.h"
|
||||
#include "plstr.h"
|
||||
#include "nsIClassInfoImpl.h"
|
||||
#include "nsIIPCSerializable.h"
|
||||
#include "nsIIPCSerializableObsolete.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/ipc/IPCSerializableParams.h"
|
||||
#include "nsIIPCSerializableInputStream.h"
|
||||
|
||||
using namespace mozilla::ipc;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// nsIStringInputStream implementation
|
||||
@ -29,7 +33,8 @@
|
||||
class nsStringInputStream MOZ_FINAL : public nsIStringInputStream
|
||||
, public nsISeekableStream
|
||||
, public nsISupportsCString
|
||||
, public nsIIPCSerializable
|
||||
, public nsIIPCSerializableObsolete
|
||||
, public nsIIPCSerializableInputStream
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
@ -38,7 +43,8 @@ public:
|
||||
NS_DECL_NSISEEKABLESTREAM
|
||||
NS_DECL_NSISUPPORTSPRIMITIVE
|
||||
NS_DECL_NSISUPPORTSCSTRING
|
||||
NS_DECL_NSIIPCSERIALIZABLE
|
||||
NS_DECL_NSIIPCSERIALIZABLEOBSOLETE
|
||||
NS_DECL_NSIIPCSERIALIZABLEINPUTSTREAM
|
||||
|
||||
nsStringInputStream()
|
||||
{
|
||||
@ -80,18 +86,18 @@ NS_IMPL_THREADSAFE_RELEASE(nsStringInputStream)
|
||||
|
||||
NS_IMPL_CLASSINFO(nsStringInputStream, NULL, nsIClassInfo::THREADSAFE,
|
||||
NS_STRINGINPUTSTREAM_CID)
|
||||
NS_IMPL_QUERY_INTERFACE5_CI(nsStringInputStream,
|
||||
NS_IMPL_QUERY_INTERFACE6_CI(nsStringInputStream,
|
||||
nsIStringInputStream,
|
||||
nsIInputStream,
|
||||
nsISupportsCString,
|
||||
nsISeekableStream,
|
||||
nsIIPCSerializable)
|
||||
NS_IMPL_CI_INTERFACE_GETTER5(nsStringInputStream,
|
||||
nsIIPCSerializableObsolete,
|
||||
nsIIPCSerializableInputStream)
|
||||
NS_IMPL_CI_INTERFACE_GETTER4(nsStringInputStream,
|
||||
nsIStringInputStream,
|
||||
nsIInputStream,
|
||||
nsISupportsCString,
|
||||
nsISeekableStream,
|
||||
nsIIPCSerializable)
|
||||
nsISeekableStream)
|
||||
|
||||
/////////
|
||||
// nsISupportsCString implementation
|
||||
@ -288,7 +294,7 @@ nsStringInputStream::SetEOF()
|
||||
}
|
||||
|
||||
/////////
|
||||
// nsIIPCSerializable implementation
|
||||
// nsIIPCSerializableObsolete implementation
|
||||
/////////
|
||||
|
||||
bool
|
||||
@ -316,6 +322,33 @@ nsStringInputStream::Write(IPC::Message *aMsg)
|
||||
WriteParam(aMsg, static_cast<const nsCString&>(PromiseFlatCString(mData)));
|
||||
}
|
||||
|
||||
void
|
||||
nsStringInputStream::Serialize(InputStreamParams& aParams)
|
||||
{
|
||||
StringInputStreamParams params;
|
||||
params.data() = PromiseFlatCString(mData);
|
||||
aParams = params;
|
||||
}
|
||||
|
||||
bool
|
||||
nsStringInputStream::Deserialize(const InputStreamParams& aParams)
|
||||
{
|
||||
if (aParams.type() != InputStreamParams::TStringInputStreamParams) {
|
||||
NS_ERROR("Received unknown parameters from the other process!");
|
||||
return false;
|
||||
}
|
||||
|
||||
const StringInputStreamParams& params =
|
||||
aParams.get_StringInputStreamParams();
|
||||
|
||||
if (NS_FAILED(SetData(params.data()))) {
|
||||
NS_WARNING("SetData failed!");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
nsresult
|
||||
NS_NewByteInputStream(nsIInputStream** aStreamResult,
|
||||
const char* aStringToRead, PRInt32 aLength,
|
||||
|
Loading…
Reference in New Issue
Block a user