mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 988816 - Support multiple OpenNSPRFileOpen() on RemoteOpenFile. r=aklotz, jduell
This commit is contained in:
parent
87bcf4c0d6
commit
a968b880df
@ -2991,6 +2991,14 @@ nsXMLHttpRequest::Send(nsIVariant* aVariant, const Nullable<RequestBody>& aBody)
|
||||
if (scheme.LowerCaseEqualsLiteral("app") ||
|
||||
scheme.LowerCaseEqualsLiteral("jar")) {
|
||||
mIsMappedArrayBuffer = true;
|
||||
if (XRE_GetProcessType() != GeckoProcessType_Default) {
|
||||
nsCOMPtr<nsIJARChannel> jarChannel = do_QueryInterface(mChannel);
|
||||
// For memory mapping from child process, we need to get file
|
||||
// descriptor of the JAR file opened remotely on the parent proess.
|
||||
// Set this to make sure that file descriptor can be obtained by
|
||||
// child process.
|
||||
jarChannel->EnsureChildFd();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,7 @@
|
||||
|
||||
interface nsIFile;
|
||||
|
||||
[scriptable, builtinclass, uuid(063e9698-ec67-4fe2-aa19-d21505beaa61)]
|
||||
[scriptable, builtinclass, uuid(5a4f8df0-3bd9-45c2-9db9-67e74c3dd47d)]
|
||||
interface nsIJARChannel : nsIChannel
|
||||
{
|
||||
/**
|
||||
@ -27,4 +27,11 @@ interface nsIJARChannel : nsIChannel
|
||||
* Returns the JAR file.
|
||||
*/
|
||||
readonly attribute nsIFile jarFile;
|
||||
|
||||
/**
|
||||
* For child process, set this to make sure that a valid file descriptor of
|
||||
* JAR file is always provided when calling NSPRFileDesc().
|
||||
* Must be set before Open() or AsyncOpen() to be effective.
|
||||
*/
|
||||
void ensureChildFd();
|
||||
};
|
||||
|
@ -199,6 +199,7 @@ nsJARChannel::nsJARChannel()
|
||||
, mIsPending(false)
|
||||
, mIsUnsafe(true)
|
||||
, mOpeningRemote(false)
|
||||
, mEnsureChildFd(false)
|
||||
{
|
||||
#if defined(PR_LOGGING)
|
||||
if (!gJarProtocolLog)
|
||||
@ -356,7 +357,7 @@ nsJARChannel::LookupFile()
|
||||
mJarFile = remoteFile;
|
||||
|
||||
nsIZipReaderCache *jarCache = gJarHandler->JarCache();
|
||||
if (jarCache) {
|
||||
if (jarCache && !mEnsureChildFd) {
|
||||
bool cached = false;
|
||||
rv = jarCache->IsCached(mJarFile, &cached);
|
||||
if (NS_SUCCEEDED(rv) && cached) {
|
||||
@ -368,7 +369,8 @@ nsJARChannel::LookupFile()
|
||||
|
||||
mOpeningRemote = true;
|
||||
|
||||
if (gJarHandler->RemoteOpenFileInProgress(remoteFile, this)) {
|
||||
if (gJarHandler->RemoteOpenFileInProgress(remoteFile, this) &&
|
||||
!mEnsureChildFd) {
|
||||
// JarHandler will trigger OnRemoteFileOpen() after the first
|
||||
// request for this file completes and we'll get a JAR cache
|
||||
// hit.
|
||||
@ -865,6 +867,13 @@ nsJARChannel::GetJarFile(nsIFile **aFile)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARChannel::EnsureChildFd()
|
||||
{
|
||||
mEnsureChildFd = true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// nsIDownloadObserver
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -1035,6 +1044,11 @@ nsJARChannel::OnStopRequest(nsIRequest *req, nsISupports *ctx, nsresult status)
|
||||
mCallbacks = 0;
|
||||
mProgressSink = 0;
|
||||
|
||||
if (mOpeningRemote) {
|
||||
// To deallocate file descriptor by RemoteOpenFileChild destructor.
|
||||
mJarFile = nullptr;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -93,6 +93,7 @@ private:
|
||||
bool mIsPending;
|
||||
bool mIsUnsafe;
|
||||
bool mOpeningRemote;
|
||||
bool mEnsureChildFd;
|
||||
|
||||
nsCOMPtr<nsIStreamListener> mDownloader;
|
||||
nsCOMPtr<nsIInputStreamPump> mPump;
|
||||
|
@ -72,10 +72,20 @@ NS_IMPL_ISUPPORTS(RemoteOpenFileChild,
|
||||
|
||||
RemoteOpenFileChild::RemoteOpenFileChild(const RemoteOpenFileChild& other)
|
||||
: mTabChild(other.mTabChild)
|
||||
, mNSPRFileDesc(other.mNSPRFileDesc)
|
||||
, mNSPRFileDesc(nullptr)
|
||||
, mAsyncOpenCalled(other.mAsyncOpenCalled)
|
||||
, mNSPROpenCalled(other.mNSPROpenCalled)
|
||||
{
|
||||
#if defined(XP_WIN) || defined(MOZ_WIDGET_COCOA)
|
||||
// Windows/OSX desktop builds skip remoting, so the file descriptor should
|
||||
// be nullptr here.
|
||||
MOZ_ASSERT(!other.mNSPRFileDesc);
|
||||
#else
|
||||
if (other.mNSPRFileDesc) {
|
||||
PROsfd osfd = dup(PR_FileDesc2NativeHandle(other.mNSPRFileDesc));
|
||||
mNSPRFileDesc = PR_ImportFile(osfd);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Note: don't clone mListener or we'll have a refcount leak.
|
||||
other.mURI->Clone(getter_AddRefs(mURI));
|
||||
if (other.mAppURI) {
|
||||
@ -123,8 +133,6 @@ RemoteOpenFileChild::~RemoteOpenFileChild()
|
||||
}
|
||||
|
||||
if (mNSPRFileDesc) {
|
||||
// If we handed out fd we shouldn't have pointer to it any more.
|
||||
MOZ_ASSERT(!mNSPROpenCalled);
|
||||
// PR_Close both closes the file and deallocates the PRFileDesc
|
||||
PR_Close(mNSPRFileDesc);
|
||||
}
|
||||
@ -347,11 +355,6 @@ RemoteOpenFileChild::Clone(nsIFile **file)
|
||||
*file = new RemoteOpenFileChild(*this);
|
||||
NS_ADDREF(*file);
|
||||
|
||||
// if we transferred ownership of file to clone, forget our pointer.
|
||||
if (mNSPRFileDesc) {
|
||||
mNSPRFileDesc = nullptr;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -370,21 +373,13 @@ RemoteOpenFileChild::OpenNSPRFileDesc(int32_t aFlags, int32_t aMode,
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
// Unlike regular nsIFile we can't (easily) support multiple open()s.
|
||||
if (mNSPROpenCalled) {
|
||||
return NS_ERROR_ALREADY_OPENED;
|
||||
}
|
||||
|
||||
if (!mNSPRFileDesc) {
|
||||
// client skipped AsyncRemoteFileOpen() or didn't wait for result, or this
|
||||
// object has been cloned
|
||||
// Client skipped AsyncRemoteFileOpen() or didn't wait for result.
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
// hand off ownership (i.e responsibility to PR_Close() file handle) to caller
|
||||
*aRetval = mNSPRFileDesc;
|
||||
mNSPRFileDesc = nullptr;
|
||||
mNSPROpenCalled = true;
|
||||
PROsfd osfd = dup(PR_FileDesc2NativeHandle(mNSPRFileDesc));
|
||||
*aRetval = PR_ImportFile(osfd);
|
||||
|
||||
return NS_OK;
|
||||
#endif
|
||||
|
@ -127,6 +127,11 @@ NS_IMETHODIMP DummyChannel::GetJarFile(nsIFile* *aFile)
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP DummyChannel::EnsureChildFd()
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP DummyChannel::Run()
|
||||
{
|
||||
nsresult rv = mListener->OnStartRequest(this, mListenerContext);
|
||||
|
Loading…
Reference in New Issue
Block a user