зеркало из https://github.com/mozilla/gecko-dev.git
Back out 4b47185f48f8 (bug 835698) for Win debug crashes in test_jarchannel_e10s.js
This commit is contained in:
Родитель
b03446be96
Коммит
a59edaacfe
|
@ -22,10 +22,7 @@ ifneq (cocoa,$(MOZ_WIDGET_TOOLKIT))
|
||||||
TEST_DIRS += tests
|
TEST_DIRS += tests
|
||||||
endif
|
endif
|
||||||
|
|
||||||
EXPORTS = \
|
EXPORTS = PCOMContentPermissionRequestChild.h
|
||||||
nsICachedFileDescriptorListener.h \
|
|
||||||
PCOMContentPermissionRequestChild.h \
|
|
||||||
$(NULL)
|
|
||||||
|
|
||||||
EXPORTS_NAMESPACES = \
|
EXPORTS_NAMESPACES = \
|
||||||
mozilla \
|
mozilla \
|
||||||
|
|
|
@ -31,7 +31,6 @@ using gfxSize;
|
||||||
using mozilla::layers::LayersBackend;
|
using mozilla::layers::LayersBackend;
|
||||||
using mozilla::layers::FrameMetrics;
|
using mozilla::layers::FrameMetrics;
|
||||||
using mozilla::layout::ScrollingBehavior;
|
using mozilla::layout::ScrollingBehavior;
|
||||||
using mozilla::void_t;
|
|
||||||
using mozilla::WindowsHandle;
|
using mozilla::WindowsHandle;
|
||||||
using nscolor;
|
using nscolor;
|
||||||
using nsCompositionEvent;
|
using nsCompositionEvent;
|
||||||
|
@ -291,8 +290,6 @@ child:
|
||||||
|
|
||||||
LoadURL(nsCString uri);
|
LoadURL(nsCString uri);
|
||||||
|
|
||||||
CacheFileDescriptor(nsString path, FileDescriptor fd);
|
|
||||||
|
|
||||||
UpdateDimensions(nsRect rect, nsIntSize size, ScreenOrientation orientation) compress;
|
UpdateDimensions(nsRect rect, nsIntSize size, ScreenOrientation orientation) compress;
|
||||||
|
|
||||||
UpdateFrame(FrameMetrics frame) compress;
|
UpdateFrame(FrameMetrics frame) compress;
|
||||||
|
|
|
@ -18,7 +18,6 @@
|
||||||
#include "mozilla/dom/PContentChild.h"
|
#include "mozilla/dom/PContentChild.h"
|
||||||
#include "mozilla/dom/PContentDialogChild.h"
|
#include "mozilla/dom/PContentDialogChild.h"
|
||||||
#include "mozilla/ipc/DocumentRendererChild.h"
|
#include "mozilla/ipc/DocumentRendererChild.h"
|
||||||
#include "mozilla/ipc/FileDescriptorUtils.h"
|
|
||||||
#include "mozilla/layers/AsyncPanZoomController.h"
|
#include "mozilla/layers/AsyncPanZoomController.h"
|
||||||
#include "mozilla/layers/CompositorChild.h"
|
#include "mozilla/layers/CompositorChild.h"
|
||||||
#include "mozilla/layers/PLayersChild.h"
|
#include "mozilla/layers/PLayersChild.h"
|
||||||
|
@ -38,7 +37,6 @@
|
||||||
#include "mozilla/dom/Element.h"
|
#include "mozilla/dom/Element.h"
|
||||||
#include "nsIAppsService.h"
|
#include "nsIAppsService.h"
|
||||||
#include "nsIBaseWindow.h"
|
#include "nsIBaseWindow.h"
|
||||||
#include "nsICachedFileDescriptorListener.h"
|
|
||||||
#include "nsIComponentManager.h"
|
#include "nsIComponentManager.h"
|
||||||
#include "nsIDocumentInlines.h"
|
#include "nsIDocumentInlines.h"
|
||||||
#include "nsIDOMClassInfo.h"
|
#include "nsIDOMClassInfo.h"
|
||||||
|
@ -123,98 +121,6 @@ public:
|
||||||
const InfallibleTArray<nsString>& aStringParams);
|
const InfallibleTArray<nsString>& aStringParams);
|
||||||
};
|
};
|
||||||
|
|
||||||
class TabChild::CachedFileDescriptorInfo
|
|
||||||
{
|
|
||||||
struct PathOnlyComparatorHelper
|
|
||||||
{
|
|
||||||
bool Equals(const nsAutoPtr<CachedFileDescriptorInfo>& a,
|
|
||||||
const CachedFileDescriptorInfo& b) const
|
|
||||||
{
|
|
||||||
return a->mPath == b.mPath;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct PathAndCallbackComparatorHelper
|
|
||||||
{
|
|
||||||
bool Equals(const nsAutoPtr<CachedFileDescriptorInfo>& a,
|
|
||||||
const CachedFileDescriptorInfo& b) const
|
|
||||||
{
|
|
||||||
return a->mPath == b.mPath &&
|
|
||||||
a->mCallback == b.mCallback;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
|
||||||
nsString mPath;
|
|
||||||
FileDescriptor mFileDescriptor;
|
|
||||||
nsCOMPtr<nsICachedFileDescriptorListener> mCallback;
|
|
||||||
bool mCanceled;
|
|
||||||
|
|
||||||
CachedFileDescriptorInfo(const nsAString& aPath)
|
|
||||||
: mPath(aPath), mCanceled(false)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
CachedFileDescriptorInfo(const nsAString& aPath,
|
|
||||||
const FileDescriptor& aFileDescriptor)
|
|
||||||
: mPath(aPath), mFileDescriptor(aFileDescriptor), mCanceled(false)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
CachedFileDescriptorInfo(const nsAString& aPath,
|
|
||||||
nsICachedFileDescriptorListener* aCallback)
|
|
||||||
: mPath(aPath), mCallback(aCallback), mCanceled(false)
|
|
||||||
{ }
|
|
||||||
|
|
||||||
PathOnlyComparatorHelper PathOnlyComparator() const
|
|
||||||
{
|
|
||||||
return PathOnlyComparatorHelper();
|
|
||||||
}
|
|
||||||
|
|
||||||
PathAndCallbackComparatorHelper PathAndCallbackComparator() const
|
|
||||||
{
|
|
||||||
return PathAndCallbackComparatorHelper();
|
|
||||||
}
|
|
||||||
|
|
||||||
void FireCallback() const
|
|
||||||
{
|
|
||||||
mCallback->OnCachedFileDescriptor(mPath, mFileDescriptor);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class TabChild::CachedFileDescriptorCallbackRunnable : public nsRunnable
|
|
||||||
{
|
|
||||||
typedef TabChild::CachedFileDescriptorInfo CachedFileDescriptorInfo;
|
|
||||||
|
|
||||||
nsAutoPtr<CachedFileDescriptorInfo> mInfo;
|
|
||||||
|
|
||||||
public:
|
|
||||||
CachedFileDescriptorCallbackRunnable(CachedFileDescriptorInfo* aInfo)
|
|
||||||
: mInfo(aInfo)
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
|
||||||
MOZ_ASSERT(aInfo);
|
|
||||||
MOZ_ASSERT(!aInfo->mPath.IsEmpty());
|
|
||||||
MOZ_ASSERT(aInfo->mCallback);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Dispatch()
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
|
||||||
|
|
||||||
nsresult rv = NS_DispatchToCurrentThread(this);
|
|
||||||
NS_ENSURE_SUCCESS_VOID(rv);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
NS_IMETHOD Run()
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
|
||||||
MOZ_ASSERT(mInfo);
|
|
||||||
|
|
||||||
mInfo->FireCallback();
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
StaticRefPtr<TabChild> sPreallocatedTab;
|
StaticRefPtr<TabChild> sPreallocatedTab;
|
||||||
|
|
||||||
/*static*/ void
|
/*static*/ void
|
||||||
|
@ -1213,130 +1119,6 @@ TabChild::RecvLoadURL(const nsCString& uri)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
|
||||||
TabChild::RecvCacheFileDescriptor(const nsString& aPath,
|
|
||||||
const FileDescriptor& aFileDescriptor)
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
|
||||||
MOZ_ASSERT(!aPath.IsEmpty());
|
|
||||||
|
|
||||||
// aFileDescriptor may be invalid here, but the callback will choose how to
|
|
||||||
// handle it.
|
|
||||||
|
|
||||||
// First see if we already have a request for this path.
|
|
||||||
const CachedFileDescriptorInfo search(aPath);
|
|
||||||
uint32_t index =
|
|
||||||
mCachedFileDescriptorInfos.IndexOf(search, 0,
|
|
||||||
search.PathOnlyComparator());
|
|
||||||
if (index == mCachedFileDescriptorInfos.NoIndex) {
|
|
||||||
// We haven't had any requests for this path yet. Assume that we will
|
|
||||||
// in a little while and save the file descriptor here.
|
|
||||||
mCachedFileDescriptorInfos.AppendElement(
|
|
||||||
new CachedFileDescriptorInfo(aPath, aFileDescriptor));
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsAutoPtr<CachedFileDescriptorInfo>& info =
|
|
||||||
mCachedFileDescriptorInfos[index];
|
|
||||||
|
|
||||||
MOZ_ASSERT(info);
|
|
||||||
MOZ_ASSERT(info->mPath == aPath);
|
|
||||||
MOZ_ASSERT(!info->mFileDescriptor.IsValid());
|
|
||||||
MOZ_ASSERT(info->mCallback);
|
|
||||||
|
|
||||||
// If this callback has been canceled then we can simply close the file
|
|
||||||
// descriptor and forget about the callback.
|
|
||||||
if (info->mCanceled) {
|
|
||||||
// Only close if this is a valid file descriptor.
|
|
||||||
if (aFileDescriptor.IsValid()) {
|
|
||||||
nsRefPtr<CloseFileRunnable> runnable =
|
|
||||||
new CloseFileRunnable(aFileDescriptor);
|
|
||||||
runnable->Dispatch();
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Not canceled so fire the callback.
|
|
||||||
info->mFileDescriptor = aFileDescriptor;
|
|
||||||
|
|
||||||
// We don't need a runnable here because we should already be at the top
|
|
||||||
// of the event loop. Just fire immediately.
|
|
||||||
info->FireCallback();
|
|
||||||
}
|
|
||||||
|
|
||||||
mCachedFileDescriptorInfos.RemoveElementAt(index);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
TabChild::GetCachedFileDescriptor(const nsAString& aPath,
|
|
||||||
nsICachedFileDescriptorListener* aCallback)
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
|
||||||
MOZ_ASSERT(!aPath.IsEmpty());
|
|
||||||
MOZ_ASSERT(aCallback);
|
|
||||||
|
|
||||||
// First see if we've already received a cached file descriptor for this
|
|
||||||
// path.
|
|
||||||
const CachedFileDescriptorInfo search(aPath);
|
|
||||||
uint32_t index =
|
|
||||||
mCachedFileDescriptorInfos.IndexOf(search, 0,
|
|
||||||
search.PathOnlyComparator());
|
|
||||||
if (index == mCachedFileDescriptorInfos.NoIndex) {
|
|
||||||
// We haven't received a file descriptor for this path yet. Assume that
|
|
||||||
// we will in a little while and save the request here.
|
|
||||||
mCachedFileDescriptorInfos.AppendElement(
|
|
||||||
new CachedFileDescriptorInfo(aPath, aCallback));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsAutoPtr<CachedFileDescriptorInfo>& info =
|
|
||||||
mCachedFileDescriptorInfos[index];
|
|
||||||
|
|
||||||
MOZ_ASSERT(info);
|
|
||||||
MOZ_ASSERT(info->mPath == aPath);
|
|
||||||
MOZ_ASSERT(!info->mCallback);
|
|
||||||
MOZ_ASSERT(!info->mCanceled);
|
|
||||||
|
|
||||||
info->mCallback = aCallback;
|
|
||||||
|
|
||||||
nsRefPtr<CachedFileDescriptorCallbackRunnable> runnable =
|
|
||||||
new CachedFileDescriptorCallbackRunnable(info);
|
|
||||||
runnable->Dispatch();
|
|
||||||
|
|
||||||
mCachedFileDescriptorInfos.RemoveElementAt(index);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
TabChild::CancelCachedFileDescriptorCallback(
|
|
||||||
const nsAString& aPath,
|
|
||||||
nsICachedFileDescriptorListener* aCallback)
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
|
||||||
MOZ_ASSERT(!aPath.IsEmpty());
|
|
||||||
MOZ_ASSERT(aCallback);
|
|
||||||
|
|
||||||
const CachedFileDescriptorInfo search(aPath, aCallback);
|
|
||||||
uint32_t index =
|
|
||||||
mCachedFileDescriptorInfos.IndexOf(search, 0,
|
|
||||||
search.PathAndCallbackComparator());
|
|
||||||
if (index == mCachedFileDescriptorInfos.NoIndex) {
|
|
||||||
// Nothing to do here.
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
nsAutoPtr<CachedFileDescriptorInfo>& info =
|
|
||||||
mCachedFileDescriptorInfos[index];
|
|
||||||
|
|
||||||
MOZ_ASSERT(info);
|
|
||||||
MOZ_ASSERT(info->mPath == aPath);
|
|
||||||
MOZ_ASSERT(!info->mFileDescriptor.IsValid());
|
|
||||||
MOZ_ASSERT(info->mCallback == aCallback);
|
|
||||||
MOZ_ASSERT(!info->mCanceled);
|
|
||||||
|
|
||||||
// Set this flag so that we will close the file descriptor when it arrives.
|
|
||||||
info->mCanceled = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
TabChild::DoFakeShow()
|
TabChild::DoFakeShow()
|
||||||
{
|
{
|
||||||
|
|
|
@ -54,7 +54,6 @@
|
||||||
#include "mozilla/dom/TabContext.h"
|
#include "mozilla/dom/TabContext.h"
|
||||||
|
|
||||||
struct gfxMatrix;
|
struct gfxMatrix;
|
||||||
class nsICachedFileDescriptorListener;
|
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace layout {
|
namespace layout {
|
||||||
|
@ -197,9 +196,6 @@ public:
|
||||||
const mozilla::dom::StructuredCloneData& aData);
|
const mozilla::dom::StructuredCloneData& aData);
|
||||||
|
|
||||||
virtual bool RecvLoadURL(const nsCString& uri);
|
virtual bool RecvLoadURL(const nsCString& uri);
|
||||||
virtual bool RecvCacheFileDescriptor(const nsString& aPath,
|
|
||||||
const FileDescriptor& aFileDescriptor)
|
|
||||||
MOZ_OVERRIDE;
|
|
||||||
virtual bool RecvShow(const nsIntSize& size);
|
virtual bool RecvShow(const nsIntSize& size);
|
||||||
virtual bool RecvUpdateDimensions(const nsRect& rect, const nsIntSize& size, const ScreenOrientation& orientation);
|
virtual bool RecvUpdateDimensions(const nsRect& rect, const nsIntSize& size, const ScreenOrientation& orientation);
|
||||||
virtual bool RecvUpdateFrame(const mozilla::layers::FrameMetrics& aFrameMetrics);
|
virtual bool RecvUpdateFrame(const mozilla::layers::FrameMetrics& aFrameMetrics);
|
||||||
|
@ -321,15 +317,6 @@ public:
|
||||||
*/
|
*/
|
||||||
void GetAppType(nsAString& aAppType) const { aAppType = mAppType; }
|
void GetAppType(nsAString& aAppType) const { aAppType = mAppType; }
|
||||||
|
|
||||||
// Returns true if the file descriptor was found in the cache, false
|
|
||||||
// otherwise.
|
|
||||||
bool GetCachedFileDescriptor(const nsAString& aPath,
|
|
||||||
nsICachedFileDescriptorListener* aCallback);
|
|
||||||
|
|
||||||
void CancelCachedFileDescriptorCallback(
|
|
||||||
const nsAString& aPath,
|
|
||||||
nsICachedFileDescriptorListener* aCallback);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual PRenderFrameChild* AllocPRenderFrame(ScrollingBehavior* aScrolling,
|
virtual PRenderFrameChild* AllocPRenderFrame(ScrollingBehavior* aScrolling,
|
||||||
LayersBackend* aBackend,
|
LayersBackend* aBackend,
|
||||||
|
@ -425,9 +412,6 @@ private:
|
||||||
return utils;
|
return utils;
|
||||||
}
|
}
|
||||||
|
|
||||||
class CachedFileDescriptorInfo;
|
|
||||||
class CachedFileDescriptorCallbackRunnable;
|
|
||||||
|
|
||||||
nsCOMPtr<nsIWebNavigation> mWebNav;
|
nsCOMPtr<nsIWebNavigation> mWebNav;
|
||||||
nsCOMPtr<nsIWidget> mWidget;
|
nsCOMPtr<nsIWidget> mWidget;
|
||||||
nsCOMPtr<nsIURI> mLastURI;
|
nsCOMPtr<nsIURI> mLastURI;
|
||||||
|
@ -446,9 +430,6 @@ private:
|
||||||
// the touch we're tracking. That is, if touchend or a touchmove
|
// the touch we're tracking. That is, if touchend or a touchmove
|
||||||
// that exceeds the gesture threshold doesn't happen.
|
// that exceeds the gesture threshold doesn't happen.
|
||||||
CancelableTask* mTapHoldTimer;
|
CancelableTask* mTapHoldTimer;
|
||||||
// At present only 1 of these is really expected.
|
|
||||||
nsAutoTArray<nsAutoPtr<CachedFileDescriptorInfo>, 1>
|
|
||||||
mCachedFileDescriptorInfos;
|
|
||||||
float mOldViewportWidth;
|
float mOldViewportWidth;
|
||||||
nscolor mLastBackgroundColor;
|
nscolor mLastBackgroundColor;
|
||||||
ScrollingBehavior mScrolling;
|
ScrollingBehavior mScrolling;
|
||||||
|
|
|
@ -50,7 +50,6 @@
|
||||||
#include "nsSerializationHelper.h"
|
#include "nsSerializationHelper.h"
|
||||||
#include "nsServiceManagerUtils.h"
|
#include "nsServiceManagerUtils.h"
|
||||||
#include "nsThreadUtils.h"
|
#include "nsThreadUtils.h"
|
||||||
#include "private/pprio.h"
|
|
||||||
#include "StructuredCloneUtils.h"
|
#include "StructuredCloneUtils.h"
|
||||||
#include "TabChild.h"
|
#include "TabChild.h"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
@ -67,116 +66,6 @@ using namespace mozilla::dom::indexedDB;
|
||||||
// from the ones registered by webProgressListeners.
|
// from the ones registered by webProgressListeners.
|
||||||
#define NOTIFY_FLAG_SHIFT 16
|
#define NOTIFY_FLAG_SHIFT 16
|
||||||
|
|
||||||
class OpenFileAndSendFDRunnable : public nsRunnable
|
|
||||||
{
|
|
||||||
const nsString mPath;
|
|
||||||
nsRefPtr<TabParent> mTabParent;
|
|
||||||
nsCOMPtr<nsIEventTarget> mEventTarget;
|
|
||||||
PRFileDesc* mFD;
|
|
||||||
|
|
||||||
public:
|
|
||||||
OpenFileAndSendFDRunnable(const nsAString& aPath, TabParent* aTabParent)
|
|
||||||
: mPath(aPath), mTabParent(aTabParent), mFD(nullptr)
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
|
||||||
MOZ_ASSERT(!aPath.IsEmpty());
|
|
||||||
MOZ_ASSERT(aTabParent);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Dispatch()
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
|
||||||
|
|
||||||
mEventTarget = do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
|
|
||||||
NS_ENSURE_TRUE_VOID(mEventTarget);
|
|
||||||
|
|
||||||
nsresult rv = mEventTarget->Dispatch(this, NS_DISPATCH_NORMAL);
|
|
||||||
NS_ENSURE_SUCCESS_VOID(rv);
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
~OpenFileAndSendFDRunnable()
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(!mFD);
|
|
||||||
}
|
|
||||||
|
|
||||||
// This shouldn't be called directly except by the event loop. Use Dispatch
|
|
||||||
// to start the sequence.
|
|
||||||
NS_IMETHOD Run()
|
|
||||||
{
|
|
||||||
if (NS_IsMainThread()) {
|
|
||||||
SendResponse();
|
|
||||||
} else if (mFD) {
|
|
||||||
CloseFile();
|
|
||||||
} else {
|
|
||||||
OpenFile();
|
|
||||||
}
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
void SendResponse()
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
|
||||||
MOZ_ASSERT(mTabParent);
|
|
||||||
MOZ_ASSERT(mEventTarget);
|
|
||||||
MOZ_ASSERT(mFD);
|
|
||||||
|
|
||||||
nsRefPtr<TabParent> tabParent;
|
|
||||||
mTabParent.swap(tabParent);
|
|
||||||
|
|
||||||
FileDescriptor::PlatformHandleType handle =
|
|
||||||
FileDescriptor::PlatformHandleType(PR_FileDesc2NativeHandle(mFD));
|
|
||||||
|
|
||||||
mozilla::unused << tabParent->SendCacheFileDescriptor(mPath, handle);
|
|
||||||
|
|
||||||
nsCOMPtr<nsIEventTarget> eventTarget;
|
|
||||||
mEventTarget.swap(eventTarget);
|
|
||||||
|
|
||||||
if (NS_FAILED(eventTarget->Dispatch(this, NS_DISPATCH_NORMAL))) {
|
|
||||||
NS_WARNING("Failed to dispatch to stream transport service!");
|
|
||||||
|
|
||||||
// It's probably safer to take the main thread IO hit here rather
|
|
||||||
// than leak a file descriptor.
|
|
||||||
CloseFile();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void OpenFile()
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(!NS_IsMainThread());
|
|
||||||
MOZ_ASSERT(!mFD);
|
|
||||||
|
|
||||||
nsCOMPtr<nsIFile> file;
|
|
||||||
nsresult rv = NS_NewLocalFile(mPath, false, getter_AddRefs(file));
|
|
||||||
NS_ENSURE_SUCCESS_VOID(rv);
|
|
||||||
|
|
||||||
PRFileDesc* fd;
|
|
||||||
rv = file->OpenNSPRFileDesc(PR_RDONLY, 0, &fd);
|
|
||||||
NS_ENSURE_SUCCESS_VOID(rv);
|
|
||||||
|
|
||||||
mFD = fd;
|
|
||||||
|
|
||||||
if (NS_FAILED(NS_DispatchToMainThread(this, NS_DISPATCH_NORMAL))) {
|
|
||||||
NS_WARNING("Failed to dispatch to main thread!");
|
|
||||||
|
|
||||||
CloseFile();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CloseFile()
|
|
||||||
{
|
|
||||||
// It's possible for this to happen on the main thread if the dispatch
|
|
||||||
// to the stream service fails after we've already opened the file so
|
|
||||||
// we can't assert the thread we're running on.
|
|
||||||
|
|
||||||
MOZ_ASSERT(mFD);
|
|
||||||
|
|
||||||
PR_Close(mFD);
|
|
||||||
mFD = nullptr;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace dom {
|
namespace dom {
|
||||||
|
|
||||||
|
@ -204,7 +93,6 @@ TabParent::TabParent(const TabContext& aContext)
|
||||||
, mUpdatedDimensions(false)
|
, mUpdatedDimensions(false)
|
||||||
, mMarkedDestroying(false)
|
, mMarkedDestroying(false)
|
||||||
, mIsDestroyed(false)
|
, mIsDestroyed(false)
|
||||||
, mAppPackageFileDescriptorSent(false)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -342,66 +230,23 @@ TabParent::AnswerCreateWindow(PBrowserParent** retval)
|
||||||
void
|
void
|
||||||
TabParent::LoadURL(nsIURI* aURI)
|
TabParent::LoadURL(nsIURI* aURI)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(aURI);
|
|
||||||
|
|
||||||
if (mIsDestroyed) {
|
if (mIsDestroyed) {
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
if (!mShown) {
|
||||||
|
nsAutoCString spec;
|
||||||
|
if (aURI) {
|
||||||
|
aURI->GetSpec(spec);
|
||||||
|
}
|
||||||
|
NS_WARNING(nsPrintfCString("TabParent::LoadURL(%s) called before "
|
||||||
|
"Show(). Ignoring LoadURL.\n", spec.get()).get());
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsCString spec;
|
nsCString spec;
|
||||||
aURI->GetSpec(spec);
|
aURI->GetSpec(spec);
|
||||||
|
|
||||||
if (!mShown) {
|
|
||||||
NS_WARNING(nsPrintfCString("TabParent::LoadURL(%s) called before "
|
|
||||||
"Show(). Ignoring LoadURL.\n",
|
|
||||||
spec.get()).get());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
unused << SendLoadURL(spec);
|
unused << SendLoadURL(spec);
|
||||||
|
|
||||||
// If this app is a packaged app then we can speed startup by sending over
|
|
||||||
// the file descriptor for the "application.zip" file that it will
|
|
||||||
// invariably request. Only do this once.
|
|
||||||
if (!mAppPackageFileDescriptorSent) {
|
|
||||||
mAppPackageFileDescriptorSent = true;
|
|
||||||
|
|
||||||
nsCOMPtr<mozIApplication> app = GetOwnOrContainingApp();
|
|
||||||
if (app) {
|
|
||||||
nsString manifestURL;
|
|
||||||
nsresult rv = app->GetManifestURL(manifestURL);
|
|
||||||
NS_ENSURE_SUCCESS_VOID(rv);
|
|
||||||
|
|
||||||
if (StringBeginsWith(manifestURL, NS_LITERAL_STRING("app:"))) {
|
|
||||||
nsString basePath;
|
|
||||||
rv = app->GetBasePath(basePath);
|
|
||||||
NS_ENSURE_SUCCESS_VOID(rv);
|
|
||||||
|
|
||||||
nsString appId;
|
|
||||||
rv = app->GetId(appId);
|
|
||||||
NS_ENSURE_SUCCESS_VOID(rv);
|
|
||||||
|
|
||||||
nsCOMPtr<nsIFile> packageFile;
|
|
||||||
rv = NS_NewLocalFile(basePath, false,
|
|
||||||
getter_AddRefs(packageFile));
|
|
||||||
NS_ENSURE_SUCCESS_VOID(rv);
|
|
||||||
|
|
||||||
rv = packageFile->Append(appId);
|
|
||||||
NS_ENSURE_SUCCESS_VOID(rv);
|
|
||||||
|
|
||||||
rv = packageFile->Append(NS_LITERAL_STRING("application.zip"));
|
|
||||||
NS_ENSURE_SUCCESS_VOID(rv);
|
|
||||||
|
|
||||||
nsString path;
|
|
||||||
rv = packageFile->GetPath(path);
|
|
||||||
NS_ENSURE_SUCCESS_VOID(rv);
|
|
||||||
|
|
||||||
nsRefPtr<OpenFileAndSendFDRunnable> openFileRunnable =
|
|
||||||
new OpenFileAndSendFDRunnable(path, this);
|
|
||||||
openFileRunnable->Dispatch();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -304,8 +304,6 @@ private:
|
||||||
// When true, the TabParent is invalid and we should not send IPC messages
|
// When true, the TabParent is invalid and we should not send IPC messages
|
||||||
// anymore.
|
// anymore.
|
||||||
bool mIsDestroyed;
|
bool mIsDestroyed;
|
||||||
// Whether we have already sent a FileDescriptor for the app package.
|
|
||||||
bool mAppPackageFileDescriptorSent;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace dom
|
} // namespace dom
|
||||||
|
|
|
@ -1,38 +0,0 @@
|
||||||
/* 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_dom_ipc_nsICachedFileDescriptorListener_h
|
|
||||||
#define mozilla_dom_ipc_nsICachedFileDescriptorListener_h
|
|
||||||
|
|
||||||
#include "nsISupports.h"
|
|
||||||
|
|
||||||
#ifndef NS_NO_VTABLE
|
|
||||||
#define NS_NO_VTABLE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define NS_ICACHEDFILEDESCRIPTORLISTENER_IID \
|
|
||||||
{0x2cedaee0, 0x6ef2, 0x4f60, {0x9a, 0x6c, 0xdf, 0x4e, 0x4d, 0x65, 0x6a, 0xf7}}
|
|
||||||
|
|
||||||
class nsAString;
|
|
||||||
|
|
||||||
namespace mozilla {
|
|
||||||
namespace ipc {
|
|
||||||
class FileDescriptor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class NS_NO_VTABLE nsICachedFileDescriptorListener : public nsISupports
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_ICACHEDFILEDESCRIPTORLISTENER_IID)
|
|
||||||
|
|
||||||
virtual void
|
|
||||||
OnCachedFileDescriptor(const nsAString& aPath,
|
|
||||||
const mozilla::ipc::FileDescriptor& aFD) = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsICachedFileDescriptorListener,
|
|
||||||
NS_ICACHEDFILEDESCRIPTORLISTENER_IID)
|
|
||||||
|
|
||||||
#endif // mozilla_dom_ipc_nsICachedFileDescriptorListener_h
|
|
|
@ -42,8 +42,7 @@ FileDescriptor::FileDescriptor(PlatformHandleType aHandle)
|
||||||
void
|
void
|
||||||
FileDescriptor::DuplicateInCurrentProcess(PlatformHandleType aHandle)
|
FileDescriptor::DuplicateInCurrentProcess(PlatformHandleType aHandle)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT_IF(mHandleCreatedByOtherProcess,
|
MOZ_ASSERT(!mHandleCreatedByOtherProcess);
|
||||||
mHandleCreatedByOtherProcessWasUsed);
|
|
||||||
|
|
||||||
if (IsValid(aHandle)) {
|
if (IsValid(aHandle)) {
|
||||||
PlatformHandleType newHandle;
|
PlatformHandleType newHandle;
|
||||||
|
|
|
@ -53,9 +53,7 @@ public:
|
||||||
|
|
||||||
FileDescriptor(const FileDescriptor& aOther)
|
FileDescriptor(const FileDescriptor& aOther)
|
||||||
{
|
{
|
||||||
// Don't use operator= here because that will call
|
*this = aOther;
|
||||||
// CloseCurrentProcessHandle() on this (uninitialized) object.
|
|
||||||
Assign(aOther);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
FileDescriptor(PlatformHandleType aHandle);
|
FileDescriptor(PlatformHandleType aHandle);
|
||||||
|
@ -79,7 +77,18 @@ public:
|
||||||
operator=(const FileDescriptor& aOther)
|
operator=(const FileDescriptor& aOther)
|
||||||
{
|
{
|
||||||
CloseCurrentProcessHandle();
|
CloseCurrentProcessHandle();
|
||||||
Assign(aOther);
|
|
||||||
|
if (aOther.mHandleCreatedByOtherProcess) {
|
||||||
|
mHandleCreatedByOtherProcess = true;
|
||||||
|
mHandleCreatedByOtherProcessWasUsed =
|
||||||
|
aOther.mHandleCreatedByOtherProcessWasUsed;
|
||||||
|
mHandle = aOther.PlatformHandle();
|
||||||
|
} else {
|
||||||
|
DuplicateInCurrentProcess(aOther.PlatformHandle());
|
||||||
|
mHandleCreatedByOtherProcess = false;
|
||||||
|
mHandleCreatedByOtherProcessWasUsed = false;
|
||||||
|
}
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,21 +122,6 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void
|
|
||||||
Assign(const FileDescriptor& aOther)
|
|
||||||
{
|
|
||||||
if (aOther.mHandleCreatedByOtherProcess) {
|
|
||||||
mHandleCreatedByOtherProcess = true;
|
|
||||||
mHandleCreatedByOtherProcessWasUsed =
|
|
||||||
aOther.mHandleCreatedByOtherProcessWasUsed;
|
|
||||||
mHandle = aOther.PlatformHandle();
|
|
||||||
} else {
|
|
||||||
DuplicateInCurrentProcess(aOther.PlatformHandle());
|
|
||||||
mHandleCreatedByOtherProcess = false;
|
|
||||||
mHandleCreatedByOtherProcessWasUsed = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
IsValid(PlatformHandleType aHandle);
|
IsValid(PlatformHandleType aHandle);
|
||||||
|
|
||||||
|
|
|
@ -1,81 +0,0 @@
|
||||||
/* 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 "FileDescriptorUtils.h"
|
|
||||||
|
|
||||||
#include "nsIEventTarget.h"
|
|
||||||
|
|
||||||
#include "nsCOMPtr.h"
|
|
||||||
#include "nsDebug.h"
|
|
||||||
#include "nsNetCID.h"
|
|
||||||
#include "nsServiceManagerUtils.h"
|
|
||||||
#include "nsThreadUtils.h"
|
|
||||||
#include "prio.h"
|
|
||||||
#include "private/pprio.h"
|
|
||||||
|
|
||||||
using mozilla::ipc::CloseFileRunnable;
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
|
|
||||||
CloseFileRunnable::CloseFileRunnable(const FileDescriptor& aFileDescriptor)
|
|
||||||
: mFileDescriptor(aFileDescriptor)
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
|
||||||
MOZ_ASSERT(aFileDescriptor.IsValid());
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // DEBUG
|
|
||||||
|
|
||||||
CloseFileRunnable::~CloseFileRunnable()
|
|
||||||
{
|
|
||||||
if (mFileDescriptor.IsValid()) {
|
|
||||||
// It's probably safer to take the main thread IO hit here rather than leak
|
|
||||||
// the file descriptor.
|
|
||||||
CloseFile();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMPL_THREADSAFE_ISUPPORTS1(CloseFileRunnable, nsIRunnable)
|
|
||||||
|
|
||||||
void
|
|
||||||
CloseFileRunnable::Dispatch()
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
|
||||||
|
|
||||||
nsCOMPtr<nsIEventTarget> eventTarget =
|
|
||||||
do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
|
|
||||||
NS_ENSURE_TRUE_VOID(eventTarget);
|
|
||||||
|
|
||||||
nsresult rv = eventTarget->Dispatch(this, NS_DISPATCH_NORMAL);
|
|
||||||
NS_ENSURE_SUCCESS_VOID(rv);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
CloseFileRunnable::CloseFile()
|
|
||||||
{
|
|
||||||
// It's possible for this to happen on the main thread if the dispatch to the
|
|
||||||
// stream service fails so we can't assert the thread on which we're running.
|
|
||||||
|
|
||||||
MOZ_ASSERT(mFileDescriptor.IsValid());
|
|
||||||
|
|
||||||
PRFileDesc* fd =
|
|
||||||
PR_ImportFile(PROsfd(mFileDescriptor.PlatformHandle()));
|
|
||||||
NS_WARN_IF_FALSE(fd, "Failed to import file handle!");
|
|
||||||
|
|
||||||
mFileDescriptor = FileDescriptor();
|
|
||||||
|
|
||||||
if (fd) {
|
|
||||||
PR_Close(fd);
|
|
||||||
fd = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMETHODIMP
|
|
||||||
CloseFileRunnable::Run()
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(!NS_IsMainThread());
|
|
||||||
|
|
||||||
CloseFile();
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
|
@ -1,47 +0,0 @@
|
||||||
|
|
||||||
/* 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_FileDescriptorUtils_h
|
|
||||||
#define mozilla_ipc_FileDescriptorUtils_h
|
|
||||||
|
|
||||||
#include "mozilla/ipc/FileDescriptor.h"
|
|
||||||
#include "nsIRunnable.h"
|
|
||||||
|
|
||||||
namespace mozilla {
|
|
||||||
namespace ipc {
|
|
||||||
|
|
||||||
// When Dispatch() is called (from main thread) this class arranges to close the
|
|
||||||
// provided FileDescriptor on one of the socket transport service threads (to
|
|
||||||
// avoid main thread I/O).
|
|
||||||
class CloseFileRunnable : public nsIRunnable
|
|
||||||
{
|
|
||||||
typedef mozilla::ipc::FileDescriptor FileDescriptor;
|
|
||||||
|
|
||||||
FileDescriptor mFileDescriptor;
|
|
||||||
|
|
||||||
public:
|
|
||||||
CloseFileRunnable(const FileDescriptor& aFileDescriptor)
|
|
||||||
#ifdef DEBUG
|
|
||||||
;
|
|
||||||
#else
|
|
||||||
: mFileDescriptor(aFileDescriptor)
|
|
||||||
{ }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
NS_DECL_ISUPPORTS
|
|
||||||
NS_DECL_NSIRUNNABLE
|
|
||||||
|
|
||||||
void Dispatch();
|
|
||||||
|
|
||||||
private:
|
|
||||||
~CloseFileRunnable();
|
|
||||||
|
|
||||||
void CloseFile();
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace ipc
|
|
||||||
} // namespace mozilla
|
|
||||||
|
|
||||||
#endif // mozilla_ipc_FileDescriptorUtils_h
|
|
|
@ -26,7 +26,6 @@ EXPORTS_mozilla/ipc = \
|
||||||
BrowserProcessSubThread.h \
|
BrowserProcessSubThread.h \
|
||||||
CrossProcessMutex.h \
|
CrossProcessMutex.h \
|
||||||
FileDescriptor.h \
|
FileDescriptor.h \
|
||||||
FileDescriptorUtils.h \
|
|
||||||
GeckoChildProcessHost.h \
|
GeckoChildProcessHost.h \
|
||||||
InputStreamUtils.h \
|
InputStreamUtils.h \
|
||||||
IOThreadChild.h \
|
IOThreadChild.h \
|
||||||
|
@ -72,7 +71,6 @@ CPPSRCS += \
|
||||||
AsyncChannel.cpp \
|
AsyncChannel.cpp \
|
||||||
BrowserProcessSubThread.cpp \
|
BrowserProcessSubThread.cpp \
|
||||||
FileDescriptor.cpp \
|
FileDescriptor.cpp \
|
||||||
FileDescriptorUtils.cpp \
|
|
||||||
GeckoChildProcessHost.cpp \
|
GeckoChildProcessHost.cpp \
|
||||||
InputStreamUtils.cpp \
|
InputStreamUtils.cpp \
|
||||||
MessagePump.cpp \
|
MessagePump.cpp \
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include "nsIScriptSecurityManager.h"
|
#include "nsIScriptSecurityManager.h"
|
||||||
#include "nsIPrincipal.h"
|
#include "nsIPrincipal.h"
|
||||||
#include "nsIFileURL.h"
|
#include "nsIFileURL.h"
|
||||||
|
#include "nsXULAppAPI.h"
|
||||||
|
|
||||||
#include "mozilla/Preferences.h"
|
#include "mozilla/Preferences.h"
|
||||||
#include "mozilla/net/RemoteOpenFileChild.h"
|
#include "mozilla/net/RemoteOpenFileChild.h"
|
||||||
|
@ -348,9 +349,9 @@ nsJARChannel::LookupFile()
|
||||||
}
|
}
|
||||||
// if we're in child process and have special "remoteopenfile:://" scheme,
|
// if we're in child process and have special "remoteopenfile:://" scheme,
|
||||||
// create special nsIFile that gets file handle from parent when opened.
|
// create special nsIFile that gets file handle from parent when opened.
|
||||||
if (!mJarFile && !gJarHandler->IsMainProcess()) {
|
if (!mJarFile && XRE_GetProcessType() != GeckoProcessType_Default) {
|
||||||
nsAutoCString scheme;
|
nsAutoCString scheme;
|
||||||
rv = mJarBaseURI->GetScheme(scheme);
|
nsresult rv = mJarBaseURI->GetScheme(scheme);
|
||||||
if (NS_SUCCEEDED(rv) && scheme.EqualsLiteral("remoteopenfile")) {
|
if (NS_SUCCEEDED(rv) && scheme.EqualsLiteral("remoteopenfile")) {
|
||||||
nsRefPtr<RemoteOpenFileChild> remoteFile = new RemoteOpenFileChild();
|
nsRefPtr<RemoteOpenFileChild> remoteFile = new RemoteOpenFileChild();
|
||||||
rv = remoteFile->Init(mJarBaseURI);
|
rv = remoteFile->Init(mJarBaseURI);
|
||||||
|
@ -368,20 +369,13 @@ nsJARChannel::LookupFile()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mOpeningRemote = true;
|
|
||||||
|
|
||||||
if (gJarHandler->RemoteOpenFileInProgress(remoteFile, this)) {
|
|
||||||
// JarHandler will trigger OnRemoteFileOpen() after the first
|
|
||||||
// request for this file completes and we'll get a JAR cache
|
|
||||||
// hit.
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Open file on parent: OnRemoteFileOpenComplete called when done
|
// Open file on parent: OnRemoteFileOpenComplete called when done
|
||||||
nsCOMPtr<nsITabChild> tabChild;
|
nsCOMPtr<nsITabChild> tabChild;
|
||||||
NS_QueryNotificationCallbacks(mCallbacks, mLoadGroup, tabChild);
|
NS_QueryNotificationCallbacks(mCallbacks, mLoadGroup, tabChild);
|
||||||
rv = remoteFile->AsyncRemoteFileOpen(PR_RDONLY, this, tabChild.get());
|
rv = remoteFile->AsyncRemoteFileOpen(PR_RDONLY, this, tabChild.get());
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
|
mOpeningRemote = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// try to handle a nested jar
|
// try to handle a nested jar
|
||||||
|
@ -403,38 +397,6 @@ nsJARChannel::LookupFile()
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
|
||||||
nsJARChannel::OpenLocalFile()
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(mIsPending);
|
|
||||||
|
|
||||||
// Local files are always considered safe.
|
|
||||||
mIsUnsafe = false;
|
|
||||||
|
|
||||||
nsRefPtr<nsJARInputThunk> input;
|
|
||||||
nsresult rv = CreateJarInput(gJarHandler->JarCache(),
|
|
||||||
getter_AddRefs(input));
|
|
||||||
if (NS_SUCCEEDED(rv)) {
|
|
||||||
// Create input stream pump and call AsyncRead as a block.
|
|
||||||
rv = NS_NewInputStreamPump(getter_AddRefs(mPump), input);
|
|
||||||
if (NS_SUCCEEDED(rv))
|
|
||||||
rv = mPump->AsyncRead(this, nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
nsJARChannel::NotifyError(nsresult aError)
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(NS_FAILED(aError));
|
|
||||||
|
|
||||||
mStatus = aError;
|
|
||||||
|
|
||||||
OnStartRequest(nullptr, nullptr);
|
|
||||||
OnStopRequest(nullptr, nullptr, aError);
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// nsIRequest
|
// nsIRequest
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -787,7 +749,17 @@ nsJARChannel::AsyncOpen(nsIStreamListener *listener, nsISupports *ctx)
|
||||||
} else if (mOpeningRemote) {
|
} else if (mOpeningRemote) {
|
||||||
// nothing to do: already asked parent to open file.
|
// nothing to do: already asked parent to open file.
|
||||||
} else {
|
} else {
|
||||||
rv = OpenLocalFile();
|
// local files are always considered safe
|
||||||
|
mIsUnsafe = false;
|
||||||
|
|
||||||
|
nsRefPtr<nsJARInputThunk> input;
|
||||||
|
rv = CreateJarInput(gJarHandler->JarCache(), getter_AddRefs(input));
|
||||||
|
if (NS_SUCCEEDED(rv)) {
|
||||||
|
// create input stream pump and call AsyncRead as a block
|
||||||
|
rv = NS_NewInputStreamPump(getter_AddRefs(mPump), input);
|
||||||
|
if (NS_SUCCEEDED(rv))
|
||||||
|
rv = mPump->AsyncRead(this, nullptr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
|
@ -930,7 +902,9 @@ nsJARChannel::OnDownloadComplete(nsIDownloader *downloader,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NS_FAILED(status)) {
|
if (NS_FAILED(status)) {
|
||||||
NotifyError(status);
|
mStatus = status;
|
||||||
|
OnStartRequest(nullptr, nullptr);
|
||||||
|
OnStopRequest(nullptr, nullptr, status);
|
||||||
}
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
|
@ -944,19 +918,30 @@ nsJARChannel::OnRemoteFileOpenComplete(nsresult aOpenStatus)
|
||||||
{
|
{
|
||||||
nsresult rv = aOpenStatus;
|
nsresult rv = aOpenStatus;
|
||||||
|
|
||||||
// NS_ERROR_ALREADY_OPENED here means we'll hit JAR cache in
|
if (NS_SUCCEEDED(rv)) {
|
||||||
// OpenLocalFile().
|
// files on parent are always considered safe
|
||||||
if (NS_SUCCEEDED(rv) || rv == NS_ERROR_ALREADY_OPENED) {
|
mIsUnsafe = false;
|
||||||
rv = OpenLocalFile();
|
|
||||||
|
nsRefPtr<nsJARInputThunk> input;
|
||||||
|
rv = CreateJarInput(gJarHandler->JarCache(), getter_AddRefs(input));
|
||||||
|
if (NS_SUCCEEDED(rv)) {
|
||||||
|
// create input stream pump and call AsyncRead as a block
|
||||||
|
rv = NS_NewInputStreamPump(getter_AddRefs(mPump), input);
|
||||||
|
if (NS_SUCCEEDED(rv))
|
||||||
|
rv = mPump->AsyncRead(this, nullptr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
NotifyError(rv);
|
mStatus = rv;
|
||||||
|
OnStartRequest(nullptr, nullptr);
|
||||||
|
OnStopRequest(nullptr, nullptr, mStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// nsIStreamListener
|
// nsIStreamListener
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
|
@ -51,8 +51,6 @@ public:
|
||||||
private:
|
private:
|
||||||
nsresult CreateJarInput(nsIZipReaderCache *, nsJARInputThunk **);
|
nsresult CreateJarInput(nsIZipReaderCache *, nsJARInputThunk **);
|
||||||
nsresult LookupFile();
|
nsresult LookupFile();
|
||||||
nsresult OpenLocalFile();
|
|
||||||
void NotifyError(nsresult aError);
|
|
||||||
|
|
||||||
#if defined(PR_LOGGING)
|
#if defined(PR_LOGGING)
|
||||||
nsCString mSpec;
|
nsCString mSpec;
|
||||||
|
|
|
@ -17,10 +17,6 @@
|
||||||
#include "nsNetCID.h"
|
#include "nsNetCID.h"
|
||||||
#include "nsIMIMEService.h"
|
#include "nsIMIMEService.h"
|
||||||
#include "nsMimeTypes.h"
|
#include "nsMimeTypes.h"
|
||||||
#include "nsIRemoteOpenFileListener.h"
|
|
||||||
#include "nsIHashable.h"
|
|
||||||
#include "nsThreadUtils.h"
|
|
||||||
#include "nsXULAppAPI.h"
|
|
||||||
|
|
||||||
static NS_DEFINE_CID(kZipReaderCacheCID, NS_ZIPREADERCACHE_CID);
|
static NS_DEFINE_CID(kZipReaderCacheCID, NS_ZIPREADERCACHE_CID);
|
||||||
|
|
||||||
|
@ -31,13 +27,7 @@ static NS_DEFINE_CID(kZipReaderCacheCID, NS_ZIPREADERCACHE_CID);
|
||||||
nsJARProtocolHandler *gJarHandler = nullptr;
|
nsJARProtocolHandler *gJarHandler = nullptr;
|
||||||
|
|
||||||
nsJARProtocolHandler::nsJARProtocolHandler()
|
nsJARProtocolHandler::nsJARProtocolHandler()
|
||||||
: mIsMainProcess(XRE_GetProcessType() == GeckoProcessType_Default)
|
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
|
||||||
|
|
||||||
if (!mIsMainProcess) {
|
|
||||||
mRemoteFileListeners.Init();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nsJARProtocolHandler::~nsJARProtocolHandler()
|
nsJARProtocolHandler::~nsJARProtocolHandler()
|
||||||
|
@ -65,67 +55,6 @@ nsJARProtocolHandler::MimeService()
|
||||||
return mMimeService.get();
|
return mMimeService.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
|
||||||
nsJARProtocolHandler::RemoteOpenFileInProgress(
|
|
||||||
nsIHashable *aRemoteFile,
|
|
||||||
nsIRemoteOpenFileListener *aListener)
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
|
||||||
MOZ_ASSERT(aRemoteFile);
|
|
||||||
MOZ_ASSERT(aListener);
|
|
||||||
|
|
||||||
if (IsMainProcess()) {
|
|
||||||
MOZ_NOT_REACHED("Shouldn't be called in the main process!");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
RemoteFileListenerArray *listeners;
|
|
||||||
if (mRemoteFileListeners.Get(aRemoteFile, &listeners)) {
|
|
||||||
listeners->AppendElement(aListener);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// We deliberately don't put the listener in the new array since the first
|
|
||||||
// load is handled differently.
|
|
||||||
mRemoteFileListeners.Put(aRemoteFile, new RemoteFileListenerArray());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
nsJARProtocolHandler::RemoteOpenFileComplete(nsIHashable *aRemoteFile,
|
|
||||||
nsresult aStatus)
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(NS_IsMainThread());
|
|
||||||
MOZ_ASSERT(aRemoteFile);
|
|
||||||
|
|
||||||
if (IsMainProcess()) {
|
|
||||||
MOZ_NOT_REACHED("Shouldn't be called in the main process!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
RemoteFileListenerArray *tempListeners;
|
|
||||||
if (!mRemoteFileListeners.Get(aRemoteFile, &tempListeners)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Save the listeners in a stack array. The call to Remove() below will
|
|
||||||
// delete the tempListeners array.
|
|
||||||
RemoteFileListenerArray listeners;
|
|
||||||
tempListeners->SwapElements(listeners);
|
|
||||||
|
|
||||||
mRemoteFileListeners.Remove(aRemoteFile);
|
|
||||||
|
|
||||||
// Technically we must fail OnRemoteFileComplete() since OpenNSPRFileDesc()
|
|
||||||
// won't succeed here. We've trained nsJARChannel to recognize
|
|
||||||
// NS_ERROR_ALREADY_OPENED in this case as "proceed to JAR cache hit."
|
|
||||||
nsresult status = NS_SUCCEEDED(aStatus) ? NS_ERROR_ALREADY_OPENED : aStatus;
|
|
||||||
|
|
||||||
uint32_t count = listeners.Length();
|
|
||||||
for (uint32_t index = 0; index < count; index++) {
|
|
||||||
listeners[index]->OnRemoteFileOpenComplete(status);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
NS_IMPL_THREADSAFE_ISUPPORTS3(nsJARProtocolHandler,
|
NS_IMPL_THREADSAFE_ISUPPORTS3(nsJARProtocolHandler,
|
||||||
nsIJARProtocolHandler,
|
nsIJARProtocolHandler,
|
||||||
nsIProtocolHandler,
|
nsIProtocolHandler,
|
||||||
|
|
|
@ -13,18 +13,10 @@
|
||||||
#include "nsIMIMEService.h"
|
#include "nsIMIMEService.h"
|
||||||
#include "nsWeakReference.h"
|
#include "nsWeakReference.h"
|
||||||
#include "nsCOMPtr.h"
|
#include "nsCOMPtr.h"
|
||||||
#include "nsClassHashtable.h"
|
|
||||||
#include "nsHashKeys.h"
|
|
||||||
|
|
||||||
class nsIHashable;
|
|
||||||
class nsIRemoteOpenFileListener;
|
|
||||||
|
|
||||||
class nsJARProtocolHandler : public nsIJARProtocolHandler
|
class nsJARProtocolHandler : public nsIJARProtocolHandler
|
||||||
, public nsSupportsWeakReference
|
, public nsSupportsWeakReference
|
||||||
{
|
{
|
||||||
typedef nsAutoTArray<nsCOMPtr<nsIRemoteOpenFileListener>, 5>
|
|
||||||
RemoteFileListenerArray;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NS_DECL_ISUPPORTS
|
NS_DECL_ISUPPORTS
|
||||||
NS_DECL_NSIPROTOCOLHANDLER
|
NS_DECL_NSIPROTOCOLHANDLER
|
||||||
|
@ -42,22 +34,9 @@ public:
|
||||||
nsIMIMEService *MimeService();
|
nsIMIMEService *MimeService();
|
||||||
nsIZipReaderCache *JarCache() { return mJARCache; }
|
nsIZipReaderCache *JarCache() { return mJARCache; }
|
||||||
|
|
||||||
bool IsMainProcess() const { return mIsMainProcess; }
|
|
||||||
|
|
||||||
bool RemoteOpenFileInProgress(nsIHashable *aRemoteFile,
|
|
||||||
nsIRemoteOpenFileListener *aListener);
|
|
||||||
void RemoteOpenFileComplete(nsIHashable *aRemoteFile, nsresult aStatus);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
nsCOMPtr<nsIZipReaderCache> mJARCache;
|
nsCOMPtr<nsIZipReaderCache> mJARCache;
|
||||||
nsCOMPtr<nsIMIMEService> mMimeService;
|
nsCOMPtr<nsIMIMEService> mMimeService;
|
||||||
|
|
||||||
// Holds lists of RemoteOpenFileChild (not including the 1st) that have
|
|
||||||
// requested the same file from parent.
|
|
||||||
nsClassHashtable<nsHashableHashKey, RemoteFileListenerArray>
|
|
||||||
mRemoteFileListeners;
|
|
||||||
|
|
||||||
bool mIsMainProcess;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern nsJARProtocolHandler *gJarHandler;
|
extern nsJARProtocolHandler *gJarHandler;
|
||||||
|
|
|
@ -46,7 +46,6 @@ CPPSRCS = \
|
||||||
LOCAL_INCLUDES += \
|
LOCAL_INCLUDES += \
|
||||||
-I$(srcdir)/../protocol/http \
|
-I$(srcdir)/../protocol/http \
|
||||||
-I$(srcdir)/../base/src \
|
-I$(srcdir)/../base/src \
|
||||||
-I$(topsrcdir)/modules/libjar \
|
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
include $(topsrcdir)/config/config.mk
|
include $(topsrcdir)/config/config.mk
|
||||||
|
|
|
@ -4,14 +4,10 @@
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* 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/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
#include "mozilla/net/RemoteOpenFileChild.h"
|
|
||||||
|
|
||||||
#include "mozilla/ipc/FileDescriptor.h"
|
|
||||||
#include "mozilla/ipc/FileDescriptorUtils.h"
|
|
||||||
#include "mozilla/ipc/URIUtils.h"
|
|
||||||
#include "mozilla/net/NeckoChild.h"
|
#include "mozilla/net/NeckoChild.h"
|
||||||
#include "nsJARProtocolHandler.h"
|
#include "mozilla/net/RemoteOpenFileChild.h"
|
||||||
#include "nsIRemoteOpenFileListener.h"
|
#include "nsIRemoteOpenFileListener.h"
|
||||||
|
#include "mozilla/ipc/URIUtils.h"
|
||||||
|
|
||||||
// needed to alloc/free NSPR file descriptors
|
// needed to alloc/free NSPR file descriptors
|
||||||
#include "private/pprio.h"
|
#include "private/pprio.h"
|
||||||
|
@ -21,14 +17,13 @@ using namespace mozilla::ipc;
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace net {
|
namespace net {
|
||||||
|
|
||||||
NS_IMPL_THREADSAFE_ISUPPORTS3(RemoteOpenFileChild,
|
NS_IMPL_THREADSAFE_ISUPPORTS2(RemoteOpenFileChild,
|
||||||
nsIFile,
|
nsIFile,
|
||||||
nsIHashable,
|
nsIHashable)
|
||||||
nsICachedFileDescriptorListener)
|
|
||||||
|
|
||||||
RemoteOpenFileChild::RemoteOpenFileChild(const RemoteOpenFileChild& other)
|
RemoteOpenFileChild::RemoteOpenFileChild(const RemoteOpenFileChild& other)
|
||||||
: mTabChild(other.mTabChild)
|
: mNSPRFileDesc(other.mNSPRFileDesc)
|
||||||
, mNSPRFileDesc(other.mNSPRFileDesc)
|
|
||||||
, mAsyncOpenCalled(other.mAsyncOpenCalled)
|
, mAsyncOpenCalled(other.mAsyncOpenCalled)
|
||||||
, mNSPROpenCalled(other.mNSPROpenCalled)
|
, mNSPROpenCalled(other.mNSPROpenCalled)
|
||||||
{
|
{
|
||||||
|
@ -39,10 +34,6 @@ RemoteOpenFileChild::RemoteOpenFileChild(const RemoteOpenFileChild& other)
|
||||||
|
|
||||||
RemoteOpenFileChild::~RemoteOpenFileChild()
|
RemoteOpenFileChild::~RemoteOpenFileChild()
|
||||||
{
|
{
|
||||||
if (mListener) {
|
|
||||||
NotifyListener(NS_ERROR_UNEXPECTED);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mNSPRFileDesc) {
|
if (mNSPRFileDesc) {
|
||||||
// If we handed out fd we shouldn't have pointer to it any more.
|
// If we handed out fd we shouldn't have pointer to it any more.
|
||||||
MOZ_ASSERT(!mNSPROpenCalled);
|
MOZ_ASSERT(!mNSPROpenCalled);
|
||||||
|
@ -111,9 +102,11 @@ RemoteOpenFileChild::AsyncRemoteFileOpen(int32_t aFlags,
|
||||||
return NS_ERROR_NOT_AVAILABLE;
|
return NS_ERROR_NOT_AVAILABLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
mTabChild = static_cast<TabChild*>(aTabChild);
|
mozilla::dom::TabChild* tabChild = nullptr;
|
||||||
|
if (aTabChild) {
|
||||||
if (MissingRequiredTabChild(mTabChild, "remoteopenfile")) {
|
tabChild = static_cast<mozilla::dom::TabChild*>(aTabChild);
|
||||||
|
}
|
||||||
|
if (MissingRequiredTabChild(tabChild, "remoteopenfile")) {
|
||||||
return NS_ERROR_ILLEGAL_VALUE;
|
return NS_ERROR_ILLEGAL_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,23 +117,10 @@ RemoteOpenFileChild::AsyncRemoteFileOpen(int32_t aFlags,
|
||||||
mAsyncOpenCalled = true;
|
mAsyncOpenCalled = true;
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
#else
|
#else
|
||||||
nsString path;
|
|
||||||
if (NS_FAILED(mFile->GetPath(path))) {
|
|
||||||
MOZ_NOT_REACHED("Couldn't get path from file!");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mTabChild) {
|
|
||||||
if (mTabChild->GetCachedFileDescriptor(path, this)) {
|
|
||||||
// The file descriptor was found in the cache and OnCachedFileDescriptor()
|
|
||||||
// will be called with it.
|
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
URIParams uri;
|
URIParams uri;
|
||||||
SerializeURI(mURI, uri);
|
SerializeURI(mURI, uri);
|
||||||
|
|
||||||
gNeckoChild->SendPRemoteOpenFileConstructor(this, uri, mTabChild);
|
gNeckoChild->SendPRemoteOpenFileConstructor(this, uri, tabChild);
|
||||||
|
|
||||||
// Can't seem to reply from within IPDL Parent constructor, so send open as
|
// Can't seem to reply from within IPDL Parent constructor, so send open as
|
||||||
// separate message
|
// separate message
|
||||||
|
@ -155,86 +135,6 @@ RemoteOpenFileChild::AsyncRemoteFileOpen(int32_t aFlags,
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
RemoteOpenFileChild::OnCachedFileDescriptor(const nsAString& aPath,
|
|
||||||
const FileDescriptor& aFD)
|
|
||||||
{
|
|
||||||
#ifdef DEBUG
|
|
||||||
if (!aPath.IsEmpty()) {
|
|
||||||
MOZ_ASSERT(mFile);
|
|
||||||
|
|
||||||
nsString path;
|
|
||||||
if (NS_FAILED(mFile->GetPath(path))) {
|
|
||||||
MOZ_NOT_REACHED("Couldn't get path from file!");
|
|
||||||
}
|
|
||||||
|
|
||||||
MOZ_ASSERT(path == aPath, "Paths don't match!");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
HandleFileDescriptorAndNotifyListener(aFD, /* aFromRecvFileOpened */ false);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
RemoteOpenFileChild::HandleFileDescriptorAndNotifyListener(
|
|
||||||
const FileDescriptor& aFD,
|
|
||||||
bool aFromRecvFileOpened)
|
|
||||||
{
|
|
||||||
#if defined(XP_WIN) || defined(MOZ_WIDGET_COCOA)
|
|
||||||
MOZ_NOT_REACHED("OS X and Windows shouldn't be doing IPDL here");
|
|
||||||
#else
|
|
||||||
if (!mListener) {
|
|
||||||
// We already notified our listener (either in response to a cached file
|
|
||||||
// descriptor callback or through the normal messaging mechanism). Close the
|
|
||||||
// file descriptor if it is valid.
|
|
||||||
if (aFD.IsValid()) {
|
|
||||||
nsRefPtr<CloseFileRunnable> runnable = new CloseFileRunnable(aFD);
|
|
||||||
runnable->Dispatch();
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
MOZ_ASSERT(!mNSPRFileDesc);
|
|
||||||
|
|
||||||
nsRefPtr<TabChild> tabChild;
|
|
||||||
mTabChild.swap(tabChild);
|
|
||||||
|
|
||||||
// If there is a pending callback and we're being called from IPDL then we
|
|
||||||
// need to cancel it.
|
|
||||||
if (tabChild && aFromRecvFileOpened) {
|
|
||||||
nsString path;
|
|
||||||
if (NS_FAILED(mFile->GetPath(path))) {
|
|
||||||
MOZ_NOT_REACHED("Couldn't get path from file!");
|
|
||||||
}
|
|
||||||
|
|
||||||
tabChild->CancelCachedFileDescriptorCallback(path, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (aFD.IsValid()) {
|
|
||||||
mNSPRFileDesc = PR_ImportFile(aFD.PlatformHandle());
|
|
||||||
if (!mNSPRFileDesc) {
|
|
||||||
NS_WARNING("Failed to import file handle!");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
NotifyListener(mNSPRFileDesc ? NS_OK : NS_ERROR_FILE_NOT_FOUND);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
RemoteOpenFileChild::NotifyListener(nsresult aResult)
|
|
||||||
{
|
|
||||||
MOZ_ASSERT(mListener);
|
|
||||||
mListener->OnRemoteFileOpenComplete(aResult);
|
|
||||||
mListener = nullptr; // release ref to listener
|
|
||||||
|
|
||||||
nsRefPtr<nsJARProtocolHandler> handler(gJarHandler);
|
|
||||||
NS_WARN_IF_FALSE(handler, "nsJARProtocolHandler is already gone!");
|
|
||||||
|
|
||||||
if (handler) {
|
|
||||||
handler->RemoteOpenFileComplete(this, aResult);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// RemoteOpenFileChild::PRemoteOpenFileChild
|
// RemoteOpenFileChild::PRemoteOpenFileChild
|
||||||
|
@ -244,9 +144,18 @@ bool
|
||||||
RemoteOpenFileChild::RecvFileOpened(const FileDescriptor& aFD)
|
RemoteOpenFileChild::RecvFileOpened(const FileDescriptor& aFD)
|
||||||
{
|
{
|
||||||
#if defined(XP_WIN) || defined(MOZ_WIDGET_COCOA)
|
#if defined(XP_WIN) || defined(MOZ_WIDGET_COCOA)
|
||||||
NS_NOTREACHED("OS X and Windows shouldn't be doing IPDL here");
|
NS_NOTREACHED("osX and Windows shouldn't be doing IPDL here");
|
||||||
#else
|
#else
|
||||||
HandleFileDescriptorAndNotifyListener(aFD, /* aFromRecvFileOpened */ true);
|
if (!aFD.IsValid()) {
|
||||||
|
return RecvFileDidNotOpen();
|
||||||
|
}
|
||||||
|
|
||||||
|
MOZ_ASSERT(!mNSPRFileDesc);
|
||||||
|
mNSPRFileDesc = PR_AllocFileDesc(aFD.PlatformHandle(), PR_GetFileMethods());
|
||||||
|
|
||||||
|
MOZ_ASSERT(mListener);
|
||||||
|
mListener->OnRemoteFileOpenComplete(NS_OK);
|
||||||
|
mListener = nullptr; // release ref to listener
|
||||||
|
|
||||||
// This calls NeckoChild::DeallocPRemoteOpenFile(), which deletes |this| if
|
// This calls NeckoChild::DeallocPRemoteOpenFile(), which deletes |this| if
|
||||||
// IPDL holds the last reference. Don't rely on |this| existing after here!
|
// IPDL holds the last reference. Don't rely on |this| existing after here!
|
||||||
|
@ -260,10 +169,14 @@ bool
|
||||||
RemoteOpenFileChild::RecvFileDidNotOpen()
|
RemoteOpenFileChild::RecvFileDidNotOpen()
|
||||||
{
|
{
|
||||||
#if defined(XP_WIN) || defined(MOZ_WIDGET_COCOA)
|
#if defined(XP_WIN) || defined(MOZ_WIDGET_COCOA)
|
||||||
NS_NOTREACHED("OS X and Windows shouldn't be doing IPDL here");
|
NS_NOTREACHED("osX and Windows shouldn't be doing IPDL here");
|
||||||
#else
|
#else
|
||||||
HandleFileDescriptorAndNotifyListener(FileDescriptor(),
|
MOZ_ASSERT(!mNSPRFileDesc);
|
||||||
/* aFromRecvFileOpened */ true);
|
printf_stderr("RemoteOpenFileChild: file was not opened!\n");
|
||||||
|
|
||||||
|
MOZ_ASSERT(mListener);
|
||||||
|
mListener->OnRemoteFileOpenComplete(NS_ERROR_FILE_NOT_FOUND);
|
||||||
|
mListener = nullptr; // release ref to listener
|
||||||
|
|
||||||
// This calls NeckoChild::DeallocPRemoteOpenFile(), which deletes |this| if
|
// This calls NeckoChild::DeallocPRemoteOpenFile(), which deletes |this| if
|
||||||
// IPDL holds the last reference. Don't rely on |this| existing after here!
|
// IPDL holds the last reference. Don't rely on |this| existing after here!
|
||||||
|
@ -273,6 +186,24 @@ RemoteOpenFileChild::RecvFileDidNotOpen()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
RemoteOpenFileChild::AddIPDLReference()
|
||||||
|
{
|
||||||
|
AddRef();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
RemoteOpenFileChild::ReleaseIPDLReference()
|
||||||
|
{
|
||||||
|
// if we haven't gotten fd from parent yet, we're not going to.
|
||||||
|
if (mListener) {
|
||||||
|
mListener->OnRemoteFileOpenComplete(NS_ERROR_UNEXPECTED);
|
||||||
|
mListener = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
Release();
|
||||||
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// RemoteOpenFileChild::nsIFile functions that we override logic for
|
// RemoteOpenFileChild::nsIFile functions that we override logic for
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -731,3 +662,4 @@ RemoteOpenFileChild::GetHashCode(uint32_t *aResult)
|
||||||
|
|
||||||
} // namespace net
|
} // namespace net
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
||||||
|
|
|
@ -9,16 +9,10 @@
|
||||||
|
|
||||||
#include "mozilla/dom/TabChild.h"
|
#include "mozilla/dom/TabChild.h"
|
||||||
#include "mozilla/net/PRemoteOpenFileChild.h"
|
#include "mozilla/net/PRemoteOpenFileChild.h"
|
||||||
#include "nsICachedFileDescriptorListener.h"
|
|
||||||
#include "nsILocalFile.h"
|
#include "nsILocalFile.h"
|
||||||
#include "nsIRemoteOpenFileListener.h"
|
#include "nsIRemoteOpenFileListener.h"
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
|
|
||||||
namespace ipc {
|
|
||||||
class FileDescriptor;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace net {
|
namespace net {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -44,11 +38,7 @@ class RemoteOpenFileChild MOZ_FINAL
|
||||||
: public PRemoteOpenFileChild
|
: public PRemoteOpenFileChild
|
||||||
, public nsIFile
|
, public nsIFile
|
||||||
, public nsIHashable
|
, public nsIHashable
|
||||||
, public nsICachedFileDescriptorListener
|
|
||||||
{
|
{
|
||||||
typedef mozilla::dom::TabChild TabChild;
|
|
||||||
typedef mozilla::ipc::FileDescriptor FileDescriptor;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RemoteOpenFileChild()
|
RemoteOpenFileChild()
|
||||||
: mNSPRFileDesc(nullptr)
|
: mNSPRFileDesc(nullptr)
|
||||||
|
@ -65,43 +55,26 @@ public:
|
||||||
// URI must be scheme 'remoteopenfile://': otherwise looks like a file:// uri.
|
// URI must be scheme 'remoteopenfile://': otherwise looks like a file:// uri.
|
||||||
nsresult Init(nsIURI* aRemoteOpenUri);
|
nsresult Init(nsIURI* aRemoteOpenUri);
|
||||||
|
|
||||||
|
void AddIPDLReference();
|
||||||
|
void ReleaseIPDLReference();
|
||||||
|
|
||||||
// Send message to parent to tell it to open file handle for file.
|
// Send message to parent to tell it to open file handle for file.
|
||||||
// TabChild is required, for IPC security.
|
// TabChild is required, for IPC security.
|
||||||
// Note: currently only PR_RDONLY is supported for 'flags'
|
// Note: currently only PR_RDONLY is supported for 'flags'
|
||||||
nsresult AsyncRemoteFileOpen(int32_t aFlags,
|
nsresult AsyncRemoteFileOpen(int32_t aFlags,
|
||||||
nsIRemoteOpenFileListener* aListener,
|
nsIRemoteOpenFileListener* aListener,
|
||||||
nsITabChild* aTabChild);
|
nsITabChild* aTabChild);
|
||||||
|
|
||||||
void ReleaseIPDLReference()
|
|
||||||
{
|
|
||||||
Release();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RemoteOpenFileChild(const RemoteOpenFileChild& other);
|
RemoteOpenFileChild(const RemoteOpenFileChild& other);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void AddIPDLReference()
|
|
||||||
{
|
|
||||||
AddRef();
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool RecvFileOpened(const FileDescriptor&);
|
virtual bool RecvFileOpened(const FileDescriptor&);
|
||||||
virtual bool RecvFileDidNotOpen();
|
virtual bool RecvFileDidNotOpen();
|
||||||
|
|
||||||
virtual void OnCachedFileDescriptor(const nsAString& aPath,
|
|
||||||
const FileDescriptor& aFD) MOZ_OVERRIDE;
|
|
||||||
|
|
||||||
void HandleFileDescriptorAndNotifyListener(const FileDescriptor&,
|
|
||||||
bool aFromRecvFileOpened);
|
|
||||||
|
|
||||||
void NotifyListener(nsresult aResult);
|
|
||||||
|
|
||||||
// regular nsIFile object, that we forward most calls to.
|
// regular nsIFile object, that we forward most calls to.
|
||||||
nsCOMPtr<nsIFile> mFile;
|
nsCOMPtr<nsIFile> mFile;
|
||||||
nsCOMPtr<nsIURI> mURI;
|
nsCOMPtr<nsIURI> mURI;
|
||||||
nsCOMPtr<nsIRemoteOpenFileListener> mListener;
|
nsCOMPtr<nsIRemoteOpenFileListener> mListener;
|
||||||
nsRefPtr<TabChild> mTabChild;
|
|
||||||
PRFileDesc* mNSPRFileDesc;
|
PRFileDesc* mNSPRFileDesc;
|
||||||
bool mAsyncOpenCalled;
|
bool mAsyncOpenCalled;
|
||||||
bool mNSPROpenCalled;
|
bool mNSPROpenCalled;
|
||||||
|
@ -111,3 +84,4 @@ protected:
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
|
||||||
#endif // _RemoteOpenFileChild_h
|
#endif // _RemoteOpenFileChild_h
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче