mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1069081 - Part 1: Always cache fd in JAR cache except Windows. r=mwu
This commit is contained in:
parent
c5eba8eff5
commit
da68acf71a
@ -2952,14 +2952,6 @@ nsXMLHttpRequest::Send(nsIVariant* aVariant, const Nullable<RequestBody>& aBody)
|
||||
if (scheme.LowerCaseEqualsLiteral("app") ||
|
||||
scheme.LowerCaseEqualsLiteral("jar")) {
|
||||
mIsMappedArrayBuffer = true;
|
||||
if (!XRE_IsParentProcess()) {
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,7 +8,7 @@
|
||||
interface nsIFile;
|
||||
interface nsIZipEntry;
|
||||
|
||||
[scriptable, builtinclass, uuid(fbdfaa6b-72dc-465e-af56-572fd13f153c)]
|
||||
[scriptable, builtinclass, uuid(1adea16e-aa6c-4201-8f71-e9ff0acfb52e)]
|
||||
interface nsIJARChannel : nsIChannel
|
||||
{
|
||||
/**
|
||||
@ -35,20 +35,6 @@ interface nsIJARChannel : nsIChannel
|
||||
*/
|
||||
readonly attribute nsIZipEntry zipEntry;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* Note that the file descriptor returned by NSPRFileDesc() is duplicated
|
||||
* from the original, which shares its file offset with the original. If
|
||||
* the file offset is modified (ex: by lseek/read/write) on one of the
|
||||
* shared descriptors, the offset is also changed for the other.
|
||||
* It can be safely used only with operations that take absolute offsets,
|
||||
* such as mmap/pread/pwrite.
|
||||
*/
|
||||
void ensureChildFd();
|
||||
|
||||
/**
|
||||
* Force the channel to skip any chack for possible interception and
|
||||
* proceed immediately to the network.
|
||||
|
@ -208,7 +208,7 @@ interface nsIZipReader : nsISupports
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsIZipReaderCache
|
||||
|
||||
[scriptable, uuid(94ecd586-d405-4801-93d3-8ac7bef81bde)]
|
||||
[scriptable, uuid(31179807-9fcd-46c4-befa-2ade209a394b)]
|
||||
interface nsIZipReaderCache : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -245,14 +245,6 @@ interface nsIZipReaderCache : nsISupports
|
||||
*/
|
||||
nsIZipReader getInnerZip(in nsIFile zipFile, in AUTF8String zipEntry);
|
||||
|
||||
/**
|
||||
* Whether to keep NSPR file descriptor for newly opened files in the cache.
|
||||
* When aMustCacheFd is enabled and a file is given, the file will be flushed
|
||||
* from the cache if its file descriptor was not cached.
|
||||
* Note: currently not supported on Windows platform.
|
||||
*/
|
||||
void setMustCacheFd(in nsIFile zipFile, in bool aMustCacheFd);
|
||||
|
||||
/**
|
||||
* Returns the cached NSPR file descriptor of the file.
|
||||
* Note: currently not supported on Windows platform.
|
||||
|
@ -141,7 +141,7 @@ nsJAR::Open(nsIFile* zipFile)
|
||||
mZip = zip;
|
||||
return NS_OK;
|
||||
}
|
||||
return mZip->OpenArchive(zipFile, mCache ? mCache->IsMustCacheFdEnabled() : false);
|
||||
return mZip->OpenArchive(zipFile);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -1047,7 +1047,6 @@ NS_IMPL_ISUPPORTS(nsZipReaderCache, nsIZipReaderCache, nsIObserver, nsISupportsW
|
||||
nsZipReaderCache::nsZipReaderCache()
|
||||
: mLock("nsZipReaderCache.mLock")
|
||||
, mZips()
|
||||
, mMustCacheFd(false)
|
||||
#ifdef ZIP_CACHE_HIT_RATE
|
||||
,
|
||||
mZipCacheLookups(0),
|
||||
@ -1202,54 +1201,6 @@ nsZipReaderCache::GetInnerZip(nsIFile* zipFile, const nsACString &entry,
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsZipReaderCache::SetMustCacheFd(nsIFile* zipFile, bool aMustCacheFd)
|
||||
{
|
||||
#if defined(XP_WIN)
|
||||
MOZ_CRASH("Not implemented");
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
#else
|
||||
|
||||
if (!aMustCacheFd) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (!zipFile) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
nsAutoCString uri;
|
||||
rv = zipFile->GetNativePath(uri);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
uri.Insert(NS_LITERAL_CSTRING("file:"), 0);
|
||||
|
||||
MutexAutoLock lock(mLock);
|
||||
|
||||
mMustCacheFd = aMustCacheFd;
|
||||
|
||||
nsRefPtr<nsJAR> zip;
|
||||
mZips.Get(uri, getter_AddRefs(zip));
|
||||
if (!zip) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// Flush the file from the cache if its file descriptor was not cached.
|
||||
PRFileDesc* fd = nullptr;
|
||||
zip->GetNSPRFileDesc(&fd);
|
||||
if (!fd) {
|
||||
#ifdef ZIP_CACHE_HIT_RATE
|
||||
mZipCacheFlushes++;
|
||||
#endif
|
||||
zip->SetZipReaderCache(nullptr);
|
||||
mZips.Remove(uri);
|
||||
}
|
||||
return NS_OK;
|
||||
#endif /* XP_WIN */
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsZipReaderCache::GetFd(nsIFile* zipFile, PRFileDesc** aRetVal)
|
||||
{
|
||||
|
@ -196,10 +196,6 @@ public:
|
||||
|
||||
nsresult ReleaseZip(nsJAR* reader);
|
||||
|
||||
bool IsMustCacheFdEnabled() {
|
||||
return mMustCacheFd;
|
||||
}
|
||||
|
||||
typedef nsRefPtrHashtable<nsCStringHashKey, nsJAR> ZipsHashtable;
|
||||
|
||||
protected:
|
||||
@ -209,7 +205,6 @@ protected:
|
||||
mozilla::Mutex mLock;
|
||||
uint32_t mCacheSize;
|
||||
ZipsHashtable mZips;
|
||||
bool mMustCacheFd;
|
||||
|
||||
#ifdef ZIP_CACHE_HIT_RATE
|
||||
uint32_t mZipCacheLookups;
|
||||
|
@ -202,7 +202,6 @@ nsJARChannel::nsJARChannel()
|
||||
, mIsPending(false)
|
||||
, mIsUnsafe(true)
|
||||
, mOpeningRemote(false)
|
||||
, mEnsureChildFd(false)
|
||||
, mSynthesizedStreamLength(0)
|
||||
, mForceNoIntercept(false)
|
||||
{
|
||||
@ -386,9 +385,6 @@ nsJARChannel::LookupFile(bool aAllowAsync)
|
||||
// file descriptor here.
|
||||
return NS_OK;
|
||||
#else
|
||||
if (!mEnsureChildFd) {
|
||||
return NS_OK;
|
||||
}
|
||||
PRFileDesc *fd = nullptr;
|
||||
jarCache->GetFd(mJarFile, &fd);
|
||||
if (fd) {
|
||||
@ -405,13 +401,6 @@ nsJARChannel::LookupFile(bool aAllowAsync)
|
||||
|
||||
mOpeningRemote = true;
|
||||
|
||||
#if defined(XP_WIN) || defined(MOZ_WIDGET_COCOA)
|
||||
#else
|
||||
if (mEnsureChildFd && jarCache) {
|
||||
jarCache->SetMustCacheFd(remoteFile, true);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (gJarHandler->RemoteOpenFileInProgress(remoteFile, this)) {
|
||||
// JarHandler will trigger OnRemoteFileOpen() after the first
|
||||
// request for this file completes and we'll get a JAR cache
|
||||
@ -1116,13 +1105,6 @@ nsJARChannel::GetZipEntry(nsIZipEntry **aZipEntry)
|
||||
return reader->GetEntry(mJarEntry, aZipEntry);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARChannel::EnsureChildFd()
|
||||
{
|
||||
mEnsureChildFd = true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJARChannel::ForceNoIntercept()
|
||||
{
|
||||
@ -1250,23 +1232,21 @@ nsJARChannel::OnRemoteFileOpenComplete(nsresult aOpenStatus)
|
||||
// Windows/OSX desktop builds skip remoting, we don't need file
|
||||
// descriptor here.
|
||||
#else
|
||||
if (mEnsureChildFd) {
|
||||
// Set file descriptor from Jar cache into remote Jar file, if it
|
||||
// has not been set previously.
|
||||
mozilla::AutoFDClose fd;
|
||||
mJarFile->OpenNSPRFileDesc(PR_RDONLY, 0, &fd.rwget());
|
||||
if (!fd) {
|
||||
nsIZipReaderCache *jarCache = gJarHandler->JarCache();
|
||||
if (!jarCache) {
|
||||
rv = NS_ERROR_FAILURE;
|
||||
}
|
||||
PRFileDesc *jar_fd = nullptr;
|
||||
jarCache->GetFd(mJarFile, &jar_fd);
|
||||
// If we failed to get fd here, an error rv would be returned
|
||||
// by SetRemoteNSPRFileDesc(), which would then stop the
|
||||
// channel by NotifyError().
|
||||
rv = SetRemoteNSPRFileDesc(jar_fd);
|
||||
// Set file descriptor from Jar cache into remote Jar file, if it
|
||||
// has not been set previously.
|
||||
mozilla::AutoFDClose fd;
|
||||
mJarFile->OpenNSPRFileDesc(PR_RDONLY, 0, &fd.rwget());
|
||||
if (!fd) {
|
||||
nsIZipReaderCache *jarCache = gJarHandler->JarCache();
|
||||
if (!jarCache) {
|
||||
rv = NS_ERROR_FAILURE;
|
||||
}
|
||||
PRFileDesc *jar_fd = nullptr;
|
||||
jarCache->GetFd(mJarFile, &jar_fd);
|
||||
// If we failed to get fd here, an error rv would be returned
|
||||
// by SetRemoteNSPRFileDesc(), which would then stop the
|
||||
// channel by NotifyError().
|
||||
rv = SetRemoteNSPRFileDesc(jar_fd);
|
||||
}
|
||||
#endif
|
||||
if (NS_SUCCEEDED(rv) || rv == NS_ERROR_ALREADY_OPENED) {
|
||||
@ -1324,14 +1304,8 @@ nsJARChannel::OnStopRequest(nsIRequest *req, nsISupports *ctx, nsresult status)
|
||||
|
||||
#if defined(XP_WIN) || defined(MOZ_WIDGET_COCOA)
|
||||
#else
|
||||
if (mEnsureChildFd) {
|
||||
nsIZipReaderCache *jarCache = gJarHandler->JarCache();
|
||||
if (jarCache) {
|
||||
jarCache->SetMustCacheFd(mJarFile, false);
|
||||
}
|
||||
// To deallocate file descriptor by RemoteOpenFileChild destructor.
|
||||
mJarFile = nullptr;
|
||||
}
|
||||
// To deallocate file descriptor by RemoteOpenFileChild destructor.
|
||||
mJarFile = nullptr;
|
||||
#endif
|
||||
|
||||
return NS_OK;
|
||||
|
@ -122,7 +122,6 @@ private:
|
||||
bool mIsPending;
|
||||
bool mIsUnsafe;
|
||||
bool mOpeningRemote;
|
||||
bool mEnsureChildFd;
|
||||
|
||||
mozilla::net::MemoryDownloader::Data mTempMem;
|
||||
nsCOMPtr<nsIInputStreamPump> mPump;
|
||||
|
@ -171,7 +171,7 @@ nsZipHandle::nsZipHandle()
|
||||
NS_IMPL_ADDREF(nsZipHandle)
|
||||
NS_IMPL_RELEASE(nsZipHandle)
|
||||
|
||||
nsresult nsZipHandle::Init(nsIFile *file, bool aMustCacheFd, nsZipHandle **ret,
|
||||
nsresult nsZipHandle::Init(nsIFile *file, nsZipHandle **ret,
|
||||
PRFileDesc **aFd)
|
||||
{
|
||||
mozilla::AutoFDClose fd;
|
||||
@ -210,9 +210,7 @@ nsresult nsZipHandle::Init(nsIFile *file, bool aMustCacheFd, nsZipHandle **ret,
|
||||
*aFd = fd.forget();
|
||||
}
|
||||
#else
|
||||
if (aMustCacheFd) {
|
||||
handle->mNSPRFileDesc = fd.forget();
|
||||
}
|
||||
handle->mNSPRFileDesc = fd.forget();
|
||||
#endif
|
||||
handle->mMap = map;
|
||||
handle->mFile.Init(file);
|
||||
@ -267,6 +265,10 @@ nsresult nsZipHandle::GetNSPRFileDesc(PRFileDesc** aNSPRFileDesc)
|
||||
}
|
||||
|
||||
*aNSPRFileDesc = mNSPRFileDesc;
|
||||
if (!mNSPRFileDesc) {
|
||||
return NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -305,15 +307,15 @@ nsresult nsZipArchive::OpenArchive(nsZipHandle *aZipHandle, PRFileDesc *aFd)
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult nsZipArchive::OpenArchive(nsIFile *aFile, bool aMustCacheFd)
|
||||
nsresult nsZipArchive::OpenArchive(nsIFile *aFile)
|
||||
{
|
||||
nsRefPtr<nsZipHandle> handle;
|
||||
#if defined(XP_WIN)
|
||||
mozilla::AutoFDClose fd;
|
||||
nsresult rv = nsZipHandle::Init(aFile, aMustCacheFd, getter_AddRefs(handle),
|
||||
nsresult rv = nsZipHandle::Init(aFile, getter_AddRefs(handle),
|
||||
&fd.rwget());
|
||||
#else
|
||||
nsresult rv = nsZipHandle::Init(aFile, aMustCacheFd, getter_AddRefs(handle));
|
||||
nsresult rv = nsZipHandle::Init(aFile, getter_AddRefs(handle));
|
||||
#endif
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
@ -121,10 +121,9 @@ public:
|
||||
* Convenience function that generates nsZipHandle
|
||||
*
|
||||
* @param aFile The file used to access the zip
|
||||
* @param aMustCacheFd Optional flag to keep the PRFileDesc in nsZipHandle
|
||||
* @return status code
|
||||
*/
|
||||
nsresult OpenArchive(nsIFile *aFile, bool aMustCacheFd = false);
|
||||
nsresult OpenArchive(nsIFile *aFile);
|
||||
|
||||
/**
|
||||
* Test the integrity of items in this archive by running
|
||||
@ -381,7 +380,7 @@ class nsZipHandle {
|
||||
friend class nsZipArchive;
|
||||
friend class mozilla::FileLocation;
|
||||
public:
|
||||
static nsresult Init(nsIFile *file, bool aMustCacheFd, nsZipHandle **ret,
|
||||
static nsresult Init(nsIFile *file, nsZipHandle **ret,
|
||||
PRFileDesc **aFd = nullptr);
|
||||
static nsresult Init(nsZipArchive *zip, const char *entry,
|
||||
nsZipHandle **ret);
|
||||
|
@ -277,20 +277,7 @@ if (inChild) {
|
||||
// Drop any JAR caches
|
||||
obs.notifyObservers(null, "chrome-flush-caches", null);
|
||||
|
||||
// Open the first channel without ensureChildFd()
|
||||
var chan_first = ios.newChannel2(uri,
|
||||
null,
|
||||
null,
|
||||
null, // aLoadingNode
|
||||
Services.scriptSecurityManager.getSystemPrincipal(),
|
||||
null, // aTriggeringPrincipal
|
||||
Ci.nsILoadInfo.SEC_NORMAL,
|
||||
Ci.nsIContentPolicy.TYPE_OTHER)
|
||||
.QueryInterface(Ci.nsIJARChannel);
|
||||
chan_first.asyncOpen(new Listener(function(l) {
|
||||
}), null);
|
||||
|
||||
// Open multiple channels with ensureChildFd()
|
||||
// Open multiple channels
|
||||
var num = 10;
|
||||
var chan = [];
|
||||
for (var i = 0; i < num; i++) {
|
||||
@ -303,12 +290,11 @@ if (inChild) {
|
||||
Ci.nsILoadInfo.SEC_NORMAL,
|
||||
Ci.nsIContentPolicy.TYPE_OTHER)
|
||||
.QueryInterface(Ci.nsIJARChannel);
|
||||
chan[i].ensureChildFd();
|
||||
chan[i].asyncOpen(new Listener(function(l) {
|
||||
}), null);
|
||||
}
|
||||
|
||||
// Open the last channel with ensureChildFd()
|
||||
// Open the last channel
|
||||
var chan_last = ios.newChannel2(uri,
|
||||
null,
|
||||
null,
|
||||
@ -318,7 +304,6 @@ if (inChild) {
|
||||
Ci.nsILoadInfo.SEC_NORMAL,
|
||||
Ci.nsIContentPolicy.TYPE_OTHER)
|
||||
.QueryInterface(Ci.nsIJARChannel);
|
||||
chan_last.ensureChildFd();
|
||||
chan_last.asyncOpen(new Listener(function(l) {
|
||||
run_next_test();
|
||||
}), null);
|
||||
|
@ -158,11 +158,6 @@ NS_IMETHODIMP DummyChannel::GetZipEntry(nsIZipEntry* *aEntry)
|
||||
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