Bug 883495 - Avoid releasing a scriptable DNS listener off the main thread. r=mcmanus
☠☠ backed out by 2def848b4ed3 ☠ ☠
authorJosh Matthews <josh@joshmatthews.net>
Wed, 19 Jun 2013 16:28:33 +0200
changeset 135636 5a3dc3d3189099e7d1b3c070ef6532c850213764
parent 135635 259e68f8843dd7c9af1766cb6092434f276c2db6
child 135637 62f26a2bab83dc5cd8f5eff0a32e751e2205ebc5
push id24847
push userkwierso@gmail.com
push dateWed, 19 Jun 2013 23:38:15 +0000
treeherdermozilla-central@8ea92aeab783 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmcmanus
bugs883495
milestone24.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 883495 - Avoid releasing a scriptable DNS listener off the main thread. r=mcmanus
netwerk/dns/nsDNSService2.cpp
--- a/netwerk/dns/nsDNSService2.cpp
+++ b/netwerk/dns/nsDNSService2.cpp
@@ -250,30 +250,34 @@ public:
 
     nsDNSAsyncRequest(nsHostResolver   *res,
                       const nsACString &host,
                       nsIDNSListener   *listener,
                       uint16_t          flags,
                       uint16_t          af)
         : mResolver(res)
         , mHost(host)
-        , mListener(listener)
+        // Sometimes aListener is a main-thread only object like XPCWrappedJS, and
+        // sometimes it's a threadsafe object like nsSocketTransport. Use a main-
+        // thread pointer holder, but disable strict enforcement of thread invariants.
+        // The AddRef implementation of XPCWrappedJS will assert if we go wrong here.
+        , mListener(new nsMainThreadPtrHolder<nsIDNSListener>(listener, false))
         , mFlags(flags)
         , mAF(af) {}
     ~nsDNSAsyncRequest() {}
 
     void OnLookupComplete(nsHostResolver *, nsHostRecord *, nsresult);
     // Returns TRUE if the DNS listener arg is the same as the member listener
     // Used in Cancellations to remove DNS requests associated with a
     // particular hostname and nsIDNSListener
     bool EqualsAsyncListener(nsIDNSListener *aListener);
 
     nsRefPtr<nsHostResolver> mResolver;
     nsCString                mHost; // hostname we're resolving
-    nsCOMPtr<nsIDNSListener> mListener;
+    nsMainThreadPtrHandle<nsIDNSListener> mListener;
     uint16_t                 mFlags;
     uint16_t                 mAF;
 };
 
 void
 nsDNSAsyncRequest::OnLookupComplete(nsHostResolver *resolver,
                                     nsHostRecord   *hostRecord,
                                     nsresult        status)
@@ -287,17 +291,16 @@ nsDNSAsyncRequest::OnLookupComplete(nsHo
         rec = new nsDNSRecord(hostRecord);
         if (!rec)
             status = NS_ERROR_OUT_OF_MEMORY;
     }
 
     MOZ_EVENT_TRACER_DONE(this, "net::dns::lookup");
 
     mListener->OnLookupComplete(this, rec, status);
-    mListener = nullptr;
 
     // release the reference to ourselves that was added before we were
     // handed off to the host resolver.
     NS_RELEASE_THIS();
 }
 
 bool
 nsDNSAsyncRequest::EqualsAsyncListener(nsIDNSListener *aListener)