Bug 833720 - shutdown thread after parsing ics calendars to avoid leaking process thread objects. r=philipp a=philipp
authorStefan Sitter <ssitter@gmail.com>
Tue, 12 Mar 2013 21:27:10 +0100
changeset 13649 867d9e2b51a604d8f544f37dc5203aeead602e82
parent 13648 5cb01469258c30a5ac1f4399477ae980fdd2812e
child 13650 ea2fbd375c07b7aa3b42748548b378424eea44cb
push id46
push userssitter@gmail.com
push dateTue, 12 Mar 2013 20:28:38 +0000
reviewersphilipp, philipp
bugs833720
Bug 833720 - shutdown thread after parsing ics calendars to avoid leaking process thread objects. r=philipp a=philipp
calendar/base/src/calICSService.cpp
calendar/base/src/calICSService.h
--- a/calendar/base/src/calICSService.cpp
+++ b/calendar/base/src/calICSService.cpp
@@ -1242,46 +1242,59 @@ calICSService::ParserWorker::Run()
         if (!comp) {
             icalcomponent_free(ical);
             status = NS_ERROR_OUT_OF_MEMORY;
         }
     } else {
         status = calIErrors::ICS_ERROR_BASE + icalerrno;
     }
 
-    nsCOMPtr<nsIRunnable> completer = new ParserWorkerCompleter(status, comp, mListener);
-    mThread->Dispatch(completer, NS_DISPATCH_NORMAL);
+    nsCOMPtr<nsIRunnable> completer = new ParserWorkerCompleter(mWorkerThread, status,
+                                                                comp, mListener);
+    mMainThread->Dispatch(completer, NS_DISPATCH_NORMAL);
 
+    mWorkerThread = nullptr;
+    mMainThread = nullptr;
     return NS_OK;
 }
 
 NS_IMETHODIMP
 calICSService::ParserWorker::ParserWorkerCompleter::Run()
 {
     mListener->OnParsingComplete(mStatus, mComp);
+
+    nsresult rv = mWorkerThread->Shutdown();
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    mWorkerThread = nullptr;
     return NS_OK;
 }
 
 NS_IMETHODIMP
 calICSService::ParseICSAsync(const nsACString& serialized,
                              calITimezoneProvider *tzProvider,
                              calIIcsComponentParsingListener *listener)
 {
     nsresult rv;
     NS_ENSURE_ARG_POINTER(listener);
 
     nsCOMPtr<nsIThread> workerThread;
     nsCOMPtr<nsIThread> currentThread;
     rv = NS_GetCurrentThread(getter_AddRefs(currentThread));
     NS_ENSURE_SUCCESS(rv, rv);
+    rv = NS_NewThread(getter_AddRefs(workerThread));
+    NS_ENSURE_SUCCESS(rv, rv);
 
-    nsCOMPtr<nsIRunnable> worker = new ParserWorker(currentThread, serialized, tzProvider, listener);
+    nsCOMPtr<nsIRunnable> worker = new ParserWorker(currentThread, workerThread,
+                                                    serialized, tzProvider, listener);
     NS_ENSURE_TRUE(worker, NS_ERROR_OUT_OF_MEMORY);
-    rv = NS_NewThread(getter_AddRefs(workerThread), worker);
+
+    rv = workerThread->Dispatch(worker, NS_DISPATCH_NORMAL);
     NS_ENSURE_SUCCESS(rv, rv);
+
     return NS_OK;
 }
 
 NS_IMETHODIMP
 calICSService::CreateIcalComponent(const nsACString &kind, calIIcalComponent **comp)
 {
     NS_ENSURE_ARG_POINTER(comp);
     icalcomponent_kind compkind =
--- a/calendar/base/src/calICSService.h
+++ b/calendar/base/src/calICSService.h
@@ -17,44 +17,49 @@ extern "C" {
 
 class calICSService : public calIICSService,
                       public nsIClassInfo,
                       public cal::XpcomBase
 {
 protected:
     class ParserWorker : public nsRunnable {
     public:
-      ParserWorker(nsIThread *callingThread,
+      ParserWorker(nsIThread *mainThread,
+                   nsIThread *workerThread,
                    const nsACString &icsString,
                    calITimezoneProvider *tzProvider,
                    calIIcsComponentParsingListener *listener) :
-        mString(icsString), mProvider(tzProvider),
-         mListener(listener), mThread(callingThread)
+        mString(icsString), mProvider(tzProvider), mListener(listener),
+        mMainThread(mainThread), mWorkerThread(workerThread)
       {
       }
 
       NS_DECL_NSIRUNNABLE
 
     protected:
       nsCString mString;
       nsCOMPtr<calITimezoneProvider> mProvider;
       nsCOMPtr<calIIcsComponentParsingListener> mListener;
-      nsCOMPtr<nsIThread> mThread;
+      nsCOMPtr<nsIThread> mMainThread;
+      nsCOMPtr<nsIThread> mWorkerThread;
 
       class ParserWorkerCompleter : public nsRunnable {
       public:
-        ParserWorkerCompleter(nsresult status,
+        ParserWorkerCompleter(nsIThread *workerThread,
+                              nsresult status,
                               calIIcalComponent *component,
                               calIIcsComponentParsingListener *listener) :
-          mListener(listener), mComp(component), mStatus(status)
+          mListener(listener), mComp(component),
+          mStatus(status), mWorkerThread(workerThread)
         {
         }
 
         NS_DECL_NSIRUNNABLE
       protected:
+        nsCOMPtr<nsIThread> mWorkerThread;
         nsCOMPtr<calIIcsComponentParsingListener> mListener;
         nsCOMPtr<calIIcalComponent> mComp;
         nsresult mStatus;
       };
     };
 public:
     calICSService();