Bug 826846 - B2G: Crash in loop if reinstall existing packaged app. r=jdm
authorJason Duell <jduell.mcbugs@gmail.com>
Tue, 08 Jan 2013 10:15:02 +0100
changeset 128739 2c0352886e9570c85026b91558b79e2143ef475d
parent 128738 e30d0716bc359f85c2f554e6098217e7a4d53e22
child 128740 d62218c7449743ade43ff890a54457d363d3c9f1
push id317
push userbbajaj@mozilla.com
push dateTue, 07 May 2013 01:20:33 +0000
treeherdermozilla-release@159a10910249 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjdm
bugs826846
milestone21.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 826846 - B2G: Crash in loop if reinstall existing packaged app. r=jdm
netwerk/ipc/PRemoteOpenFile.ipdl
netwerk/ipc/RemoteOpenFileChild.cpp
netwerk/ipc/RemoteOpenFileChild.h
netwerk/ipc/RemoteOpenFileParent.cpp
--- a/netwerk/ipc/PRemoteOpenFile.ipdl
+++ b/netwerk/ipc/PRemoteOpenFile.ipdl
@@ -21,15 +21,17 @@ protocol PRemoteOpenFile
 parent:
   // Tell parent to open file. URI to open was passed and vetted for security in
   // IPDL constructor: see NeckoParent::AllocPRemoteOpenFile()
   AsyncOpenFile();
 
   __delete__();
 
 child:
-  // success/failure code, and if NS_SUCCEEDED(rv), an open file descriptor
-  FileOpened(FileDescriptor fd, nsresult rv);
+  // Your file handle is ready, Sir...
+  FileOpened(FileDescriptor fd);
+  // Trying to send invalid fd crashes, so we need separate method for failure
+  FileDidNotOpen();
 };
 
 
 } // namespace net
 } // namespace mozilla
--- a/netwerk/ipc/RemoteOpenFileChild.cpp
+++ b/netwerk/ipc/RemoteOpenFileChild.cpp
@@ -133,36 +133,49 @@ RemoteOpenFileChild::AsyncRemoteFileOpen
 }
 
 
 //-----------------------------------------------------------------------------
 // RemoteOpenFileChild::PRemoteOpenFileChild
 //-----------------------------------------------------------------------------
 
 bool
-RemoteOpenFileChild::RecvFileOpened(const FileDescriptor& aFD,
-                                    const nsresult& aRV)
+RemoteOpenFileChild::RecvFileOpened(const FileDescriptor& aFD)
 {
 #if defined(XP_WIN) || defined(MOZ_WIDGET_COCOA)
   NS_NOTREACHED("osX and Windows shouldn't be doing IPDL here");
 #else
-  if (NS_SUCCEEDED(aRV)) {
-    mNSPRFileDesc = PR_AllocFileDesc(aFD.PlatformHandle(), PR_GetFileMethods());
-  }
+  mNSPRFileDesc = PR_AllocFileDesc(aFD.PlatformHandle(), PR_GetFileMethods());
 
   MOZ_ASSERT(mListener);
-
-  mListener->OnRemoteFileOpenComplete(aRV);
-
+  mListener->OnRemoteFileOpenComplete(NS_OK);
   mListener = nullptr;     // release ref to listener
 
   // This calls NeckoChild::DeallocPRemoteOpenFile(), which deletes |this| if
   // IPDL holds the last reference.  Don't rely on |this| existing after here!
   Send__delete__(this);
+#endif
 
+  return true;
+}
+
+bool
+RemoteOpenFileChild::RecvFileDidNotOpen()
+{
+#if defined(XP_WIN) || defined(MOZ_WIDGET_COCOA)
+  NS_NOTREACHED("osX and Windows shouldn't be doing IPDL here");
+#else
+  MOZ_ASSERT(mListener);
+  printf_stderr("RemoteOpenFileChild: file was not opened!\n");
+  mListener->OnRemoteFileOpenComplete(NS_ERROR_FILE_NOT_FOUND);
+  mListener = nullptr;     // release ref to listener
+
+  // This calls NeckoChild::DeallocPRemoteOpenFile(), which deletes |this| if
+  // IPDL holds the last reference.  Don't rely on |this| existing after here!
+  Send__delete__(this);
 #endif
 
   return true;
 }
 
 void
 RemoteOpenFileChild::AddIPDLReference()
 {
--- a/netwerk/ipc/RemoteOpenFileChild.h
+++ b/netwerk/ipc/RemoteOpenFileChild.h
@@ -63,17 +63,18 @@ public:
   // Note: currently only PR_RDONLY is supported for 'flags'
   nsresult AsyncRemoteFileOpen(int32_t aFlags,
                                nsIRemoteOpenFileListener* aListener,
                                nsITabChild* aTabChild);
 private:
   RemoteOpenFileChild(const RemoteOpenFileChild& other);
 
 protected:
-  virtual bool RecvFileOpened(const FileDescriptor&, const nsresult&);
+  virtual bool RecvFileOpened(const FileDescriptor&);
+  virtual bool RecvFileDidNotOpen();
 
   // regular nsIFile object, that we forward most calls to.
   nsCOMPtr<nsIFile> mFile;
   nsCOMPtr<nsIURI> mURI;
   nsCOMPtr<nsIRemoteOpenFileListener> mListener;
   PRFileDesc* mNSPRFileDesc;
   bool mAsyncOpenCalled;
   bool mNSPROpenCalled;
--- a/netwerk/ipc/RemoteOpenFileParent.cpp
+++ b/netwerk/ipc/RemoteOpenFileParent.cpp
@@ -45,26 +45,27 @@ RemoteOpenFileParent::RecvAsyncOpenFile(
   // TODO: make this async!
 
   nsAutoCString path;
   nsresult rv = mURI->GetFilePath(path);
   NS_UnescapeURL(path);
   if (NS_SUCCEEDED(rv)) {
     int fd = open(path.get(), O_RDONLY);
     if (fd != -1) {
-      unused << SendFileOpened(FileDescriptor(fd), NS_OK);
+      unused << SendFileOpened(FileDescriptor(fd));
       // file handle needs to stay open until it's shared with child (and IPDL
       // is async, so hasn't happened yet). Close in destructor.
       mFd = fd;
       return true;
     }
   }
 
   // Note: sending an invalid file descriptor currently kills the child process:
   // but that's ok for our use case (failing to open application.jar).
-  unused << SendFileOpened(FileDescriptor(mFd), NS_ERROR_NOT_AVAILABLE);
+  printf_stderr("RemoteOpenFileParent: file '%s' was not found!\n", path.get());
+  unused << SendFileDidNotOpen();
 #endif // OS_TYPE
 
   return true;
 }
 
 } // namespace net
 } // namespace mozilla