Bug 1069081 - Part 1: Always cache fd in JAR cache except Windows. r=mwu
authorShian-Yow Wu <swu@mozilla.com>
Thu, 30 Jul 2015 16:05:57 +0800
changeset 287033 aa72183e80c2dfed732728e6a6bd69b48c348def
parent 287032 293dd17693db3d3533d3a59dc27eab7dbe178e3b
child 287034 e2760dfabaf077b99465786a53ed8bb6d869cfbd
push id5067
push userraliiev@mozilla.com
push dateMon, 21 Sep 2015 14:04:52 +0000
treeherdermozilla-beta@14221ffe5b2f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmwu
bugs1069081
milestone42.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1069081 - Part 1: Always cache fd in JAR cache except Windows. r=mwu
dom/base/nsXMLHttpRequest.cpp
modules/libjar/nsIJARChannel.idl
modules/libjar/nsIZipReader.idl
modules/libjar/nsJAR.cpp
modules/libjar/nsJAR.h
modules/libjar/nsJARChannel.cpp
modules/libjar/nsJARChannel.h
modules/libjar/nsZipArchive.cpp
modules/libjar/nsZipArchive.h
modules/libjar/test/unit/test_jarchannel.js
netwerk/protocol/app/AppProtocolHandler.cpp
--- a/dom/base/nsXMLHttpRequest.cpp
+++ b/dom/base/nsXMLHttpRequest.cpp
@@ -2947,24 +2947,16 @@ nsXMLHttpRequest::Send(nsIVariant* aVari
       nsAutoCString scheme;
 
       rv = mChannel->GetURI(getter_AddRefs(uri));
       if (NS_SUCCEEDED(rv)) {
         uri->GetScheme(scheme);
         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();
-          }
         }
       }
     }
     // Start reading from the channel
     rv = mChannel->AsyncOpen(listener, nullptr);
   }
 
   if (NS_FAILED(rv)) {
--- a/modules/libjar/nsIJARChannel.idl
+++ b/modules/libjar/nsIJARChannel.idl
@@ -3,17 +3,17 @@
  * 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 "nsIChannel.idl"
 
 interface nsIFile;
 interface nsIZipEntry;
 
-[scriptable, builtinclass, uuid(fbdfaa6b-72dc-465e-af56-572fd13f153c)]
+[scriptable, builtinclass, uuid(1adea16e-aa6c-4201-8f71-e9ff0acfb52e)]
 interface nsIJARChannel : nsIChannel
 {
     /**
      * Returns TRUE if the JAR file is not safe (if the content type reported
      * by the server for a remote JAR is not of an expected type).  Scripting,
      * redirects, and plugins should be disabled when loading from this
      * channel.
      */
@@ -31,27 +31,13 @@ interface nsIJARChannel : nsIChannel
 
     /**
      * Returns the zip entry if the file is synchronously accessible.
      * This will work even without opening the channel.
      */
     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.
      */
     void forceNoIntercept();
 };
--- a/modules/libjar/nsIZipReader.idl
+++ b/modules/libjar/nsIZipReader.idl
@@ -203,17 +203,17 @@ interface nsIZipReader : nsISupports
     nsIX509Cert getSigningCert(in AUTF8String aEntryName);
 
     readonly attribute uint32_t manifestEntriesCount;
 };
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsIZipReaderCache
 
-[scriptable, uuid(94ecd586-d405-4801-93d3-8ac7bef81bde)]
+[scriptable, uuid(31179807-9fcd-46c4-befa-2ade209a394b)]
 interface nsIZipReaderCache : nsISupports
 {
     /**
      * Initializes a new zip reader cache. 
      * @param cacheSize - the number of released entries to maintain before
      *   beginning to throw some out (note that the number of outstanding
      *   entries can be much greater than this number -- this is the count
      *   for those otherwise unused entries)
@@ -241,24 +241,16 @@ interface nsIZipReaderCache : nsISupport
     /**
      * Returns a (possibly shared) nsIZipReader for a zip inside another zip
      *
      * See getZip
      */
     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.
      */
     PRFileDescStar getFd(in nsIFile zipFile);
 };
 
 ////////////////////////////////////////////////////////////////////////////////
 
--- a/modules/libjar/nsJAR.cpp
+++ b/modules/libjar/nsJAR.cpp
@@ -136,17 +136,17 @@ nsJAR::Open(nsIFile* zipFile)
 
   // The omnijar is special, it is opened early on and closed late
   // this avoids reopening it
   nsRefPtr<nsZipArchive> zip = mozilla::Omnijar::GetReader(zipFile);
   if (zip) {
     mZip = zip;
     return NS_OK;
   }
-  return mZip->OpenArchive(zipFile, mCache ? mCache->IsMustCacheFdEnabled() : false);
+  return mZip->OpenArchive(zipFile);
 }
 
 NS_IMETHODIMP
 nsJAR::OpenInner(nsIZipReader *aZipReader, const nsACString &aZipEntry)
 {
   NS_ENSURE_ARG_POINTER(aZipReader);
   if (mOpened) return NS_ERROR_FAILURE; // Already open!
 
@@ -1042,17 +1042,16 @@ nsJARItem::GetPermissions(uint32_t* aPer
 ////////////////////////////////////////////////////////////////////////////////
 // nsIZipReaderCache
 
 NS_IMPL_ISUPPORTS(nsZipReaderCache, nsIZipReaderCache, nsIObserver, nsISupportsWeakReference)
 
 nsZipReaderCache::nsZipReaderCache()
   : mLock("nsZipReaderCache.mLock")
   , mZips()
-  , mMustCacheFd(false)
 #ifdef ZIP_CACHE_HIT_RATE
     ,
     mZipCacheLookups(0),
     mZipCacheHits(0),
     mZipCacheFlushes(0),
     mZipSyncMisses(0)
 #endif
 {
@@ -1198,64 +1197,16 @@ nsZipReaderCache::GetInnerZip(nsIFile* z
     MOZ_ASSERT(!mZips.Contains(uri));
     mZips.Put(uri, zip);
   }
   zip.forget(result);
   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)
 {
 #if defined(XP_WIN)
   MOZ_CRASH("Not implemented");
   return NS_ERROR_NOT_IMPLEMENTED;
 #else
   if (!zipFile) {
     return NS_ERROR_FAILURE;
--- a/modules/libjar/nsJAR.h
+++ b/modules/libjar/nsJAR.h
@@ -191,30 +191,25 @@ public:
   NS_DECL_THREADSAFE_ISUPPORTS
   NS_DECL_NSIZIPREADERCACHE
   NS_DECL_NSIOBSERVER
 
   nsZipReaderCache();
 
   nsresult ReleaseZip(nsJAR* reader);
 
-  bool IsMustCacheFdEnabled() {
-    return mMustCacheFd;
-  }
-
   typedef nsRefPtrHashtable<nsCStringHashKey, nsJAR> ZipsHashtable;
 
 protected:
 
   virtual ~nsZipReaderCache();
 
   mozilla::Mutex        mLock;
   uint32_t              mCacheSize;
   ZipsHashtable         mZips;
-  bool                  mMustCacheFd;
 
 #ifdef ZIP_CACHE_HIT_RATE
   uint32_t              mZipCacheLookups;
   uint32_t              mZipCacheHits;
   uint32_t              mZipCacheFlushes;
   uint32_t              mZipSyncMisses;
 #endif
 
--- a/modules/libjar/nsJARChannel.cpp
+++ b/modules/libjar/nsJARChannel.cpp
@@ -197,17 +197,16 @@ nsJARChannel::nsJARChannel()
     : mOpened(false)
     , mAppURI(nullptr)
     , mContentLength(-1)
     , mLoadFlags(LOAD_NORMAL)
     , mStatus(NS_OK)
     , mIsPending(false)
     , mIsUnsafe(true)
     , mOpeningRemote(false)
-    , mEnsureChildFd(false)
     , mSynthesizedStreamLength(0)
     , mForceNoIntercept(false)
 {
     if (!gJarProtocolLog)
         gJarProtocolLog = PR_NewLogModule("nsJarProtocol");
 
     // hold an owning reference to the jar handler
     NS_ADDREF(gJarHandler);
@@ -381,42 +380,32 @@ nsJARChannel::LookupFile(bool aAllowAsyn
                     // When the file descriptor is needed, get it from JAR cache
                     // if available, otherwise do the remote open to get a new
                     // one.
                     #if defined(XP_WIN) || defined(MOZ_WIDGET_COCOA)
                     // Windows/OSX desktop builds skip remoting, we don't need
                     // file descriptor here.
                     return NS_OK;
                     #else
-                    if (!mEnsureChildFd) {
-                        return NS_OK;
-                    }
                     PRFileDesc *fd = nullptr;
                     jarCache->GetFd(mJarFile, &fd);
                     if (fd) {
                         return SetRemoteNSPRFileDesc(fd);
                     }
                     #endif
                 }
             }
 
             if (!aAllowAsync) {
                 mJarFile = nullptr;
                 return NS_OK;
             }
 
             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
                 // hit.
                 return NS_OK;
             }
 
             // Open file on parent: OnRemoteFileOpenComplete called when done
@@ -1112,23 +1101,16 @@ nsJARChannel::GetZipEntry(nsIZipEntry **
     rv = gJarHandler->JarCache()->GetZip(mJarFile, getter_AddRefs(reader));
     if (NS_FAILED(rv))
         return rv;
 
     return reader->GetEntry(mJarEntry, aZipEntry);
 }
 
 NS_IMETHODIMP
-nsJARChannel::EnsureChildFd()
-{
-    mEnsureChildFd = true;
-    return NS_OK;
-}
-
-NS_IMETHODIMP
 nsJARChannel::ForceNoIntercept()
 {
     mForceNoIntercept = true;
     return NS_OK;
 }
 
 //-----------------------------------------------------------------------------
 // mozilla::net::MemoryDownloader::IObserver
@@ -1245,33 +1227,31 @@ nsJARChannel::OnRemoteFileOpenComplete(n
 
     // NS_ERROR_ALREADY_OPENED here means we'll hit JAR cache in
     // OpenLocalFile().
     if (NS_SUCCEEDED(rv) || rv == NS_ERROR_ALREADY_OPENED) {
         #if defined(XP_WIN) || defined(MOZ_WIDGET_COCOA)
         // 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) {
             rv = OpenLocalFile();
         }
     }
 
     if (NS_FAILED(rv)) {
@@ -1319,24 +1299,18 @@ nsJARChannel::OnStopRequest(nsIRequest *
     mIsPending = false;
 
     // Drop notification callbacks to prevent cycles.
     mCallbacks = 0;
     mProgressSink = 0;
 
     #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;
 }
 
 NS_IMETHODIMP
 nsJARChannel::OnDataAvailable(nsIRequest *req, nsISupports *ctx,
                                nsIInputStream *stream,
--- a/modules/libjar/nsJARChannel.h
+++ b/modules/libjar/nsJARChannel.h
@@ -117,17 +117,16 @@ private:
      * empty */
     uint32_t                        mContentDisposition;
     int64_t                         mContentLength;
     uint32_t                        mLoadFlags;
     nsresult                        mStatus;
     bool                            mIsPending;
     bool                            mIsUnsafe;
     bool                            mOpeningRemote;
-    bool                            mEnsureChildFd;
 
     mozilla::net::MemoryDownloader::Data mTempMem;
     nsCOMPtr<nsIInputStreamPump>    mPump;
     // mRequest is only non-null during OnStartRequest, so we'll have a pointer
     // to the request if we get called back via RetargetDeliveryTo.
     nsCOMPtr<nsIRequest>            mRequest;
     nsCOMPtr<nsIFile>               mJarFile;
     nsCOMPtr<nsIURI>                mJarBaseURI;
--- a/modules/libjar/nsZipArchive.cpp
+++ b/modules/libjar/nsZipArchive.cpp
@@ -166,17 +166,17 @@ nsZipHandle::nsZipHandle()
   , mRefCnt(0)
 {
   MOZ_COUNT_CTOR(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;
   int32_t flags = PR_RDONLY;
 #if defined(XP_WIN)
   flags |= nsIFile::OS_READAHEAD;
 #endif
   nsresult rv = file->OpenNSPRFileDesc(flags, 0000, &fd.rwget());
@@ -205,19 +205,17 @@ nsresult nsZipHandle::Init(nsIFile *file
     return NS_ERROR_OUT_OF_MEMORY;
   }
 
 #if defined(XP_WIN)
   if (aFd) {
     *aFd = fd.forget();
   }
 #else
-  if (aMustCacheFd) {
-    handle->mNSPRFileDesc = fd.forget();
-  }
+  handle->mNSPRFileDesc = fd.forget();
 #endif
   handle->mMap = map;
   handle->mFile.Init(file);
   handle->mLen = (uint32_t) size;
   handle->mFileData = buf;
   handle.forget(ret);
   return NS_OK;
 }
@@ -262,16 +260,20 @@ int64_t nsZipHandle::SizeOfMapping()
 
 nsresult nsZipHandle::GetNSPRFileDesc(PRFileDesc** aNSPRFileDesc)
 {
   if (!aNSPRFileDesc) {
     return NS_ERROR_ILLEGAL_VALUE;
   }
 
   *aNSPRFileDesc = mNSPRFileDesc;
+  if (!mNSPRFileDesc) {
+    return NS_ERROR_NOT_AVAILABLE;
+  }
+
   return NS_OK;
 }
 
 nsZipHandle::~nsZipHandle()
 {
   if (mMap) {
     PR_MemUnmap((void *)mFileData, mLen);
     PR_CloseFileMap(mMap);
@@ -300,25 +302,25 @@ nsresult nsZipArchive::OpenArchive(nsZip
   nsresult rv = BuildFileList(aFd);
   if (NS_SUCCEEDED(rv)) {
     if (aZipHandle->mFile)
       aZipHandle->mFile.GetURIString(mURI);
   }
   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;
 
 #if defined(XP_WIN)
   return OpenArchive(handle, fd.get());
 #else
   return OpenArchive(handle);
--- a/modules/libjar/nsZipArchive.h
+++ b/modules/libjar/nsZipArchive.h
@@ -116,20 +116,19 @@ public:
   nsresult OpenArchive(nsZipHandle *aZipHandle, PRFileDesc *aFd = nullptr);
 
   /** 
    * OpenArchive 
    * 
    * 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
    * a CRC check after extracting each item into a memory 
    * buffer.  If an entry name is supplied only the 
    * specified item is tested.  Else, if null is supplied
    * then all the items in the archive are tested.
    *
@@ -376,17 +375,17 @@ public:
     return ret;
   }
 };
 
 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);
   static nsresult Init(const uint8_t* aData, uint32_t aLen,
                        nsZipHandle **aRet);
 
   NS_METHOD_(MozExternalRefCountType) AddRef(void);
   NS_METHOD_(MozExternalRefCountType) Release(void);
--- a/modules/libjar/test/unit/test_jarchannel.js
+++ b/modules/libjar/test/unit/test_jarchannel.js
@@ -272,57 +272,42 @@ if (inChild) {
      * Multiple simultaneous opening test for bug 1048615
      */
     add_test(function testSimultaneous() {
         var uri = jarBase + "/inner1.zip";
 
         // 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++) {
             chan[i] = ios.newChannel2(uri,
                                       null,
                                       null,
                                       null,      // aLoadingNode
                                       Services.scriptSecurityManager.getSystemPrincipal(),
                                       null,      // aTriggeringPrincipal
                                       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,
                                         null,      // aLoadingNode
                                         Services.scriptSecurityManager.getSystemPrincipal(),
                                         null,      // aTriggeringPrincipal
                                         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);
     });
 } // if inChild
 
 function run_test() run_next_test();
--- a/netwerk/protocol/app/AppProtocolHandler.cpp
+++ b/netwerk/protocol/app/AppProtocolHandler.cpp
@@ -153,21 +153,16 @@ NS_IMETHODIMP DummyChannel::GetJarFile(n
   return NS_ERROR_NOT_IMPLEMENTED;
 }
 
 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);
   mPending = false;
   rv = mListener->OnStopRequest(this, mListenerContext, NS_ERROR_FILE_NOT_FOUND);
   if (mLoadGroup) {
     mLoadGroup->RemoveRequest(this, mListenerContext, NS_ERROR_FILE_NOT_FOUND);
   }