michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* vim:set ts=2 sw=2 sts=2 et cindent: */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "nsCache.h" michael@0: #include "nsCacheUtils.h" michael@0: #include "nsThreadUtils.h" michael@0: michael@0: using namespace mozilla; michael@0: michael@0: class nsDestroyThreadEvent : public nsRunnable { michael@0: public: michael@0: nsDestroyThreadEvent(nsIThread *thread) michael@0: : mThread(thread) michael@0: {} michael@0: NS_IMETHOD Run() michael@0: { michael@0: mThread->Shutdown(); michael@0: return NS_OK; michael@0: } michael@0: private: michael@0: nsCOMPtr mThread; michael@0: }; michael@0: michael@0: nsShutdownThread::nsShutdownThread(nsIThread *aThread) michael@0: : mLock("nsShutdownThread.mLock") michael@0: , mCondVar(mLock, "nsShutdownThread.mCondVar") michael@0: , mThread(aThread) michael@0: { michael@0: } michael@0: michael@0: nsShutdownThread::~nsShutdownThread() michael@0: { michael@0: } michael@0: michael@0: nsresult michael@0: nsShutdownThread::Shutdown(nsIThread *aThread) michael@0: { michael@0: nsresult rv; michael@0: nsRefPtr ev = new nsDestroyThreadEvent(aThread); michael@0: rv = NS_DispatchToMainThread(ev); michael@0: if (NS_FAILED(rv)) { michael@0: NS_WARNING("Dispatching event in nsShutdownThread::Shutdown failed!"); michael@0: } michael@0: return rv; michael@0: } michael@0: michael@0: nsresult michael@0: nsShutdownThread::BlockingShutdown(nsIThread *aThread) michael@0: { michael@0: nsresult rv; michael@0: michael@0: nsRefPtr st = new nsShutdownThread(aThread); michael@0: nsCOMPtr workerThread; michael@0: michael@0: rv = NS_NewNamedThread("thread shutdown", getter_AddRefs(workerThread)); michael@0: if (NS_FAILED(rv)) { michael@0: NS_WARNING("Can't create nsShutDownThread worker thread!"); michael@0: return rv; michael@0: } michael@0: michael@0: { michael@0: MutexAutoLock lock(st->mLock); michael@0: rv = workerThread->Dispatch(st, NS_DISPATCH_NORMAL); michael@0: if (NS_FAILED(rv)) { michael@0: NS_WARNING( michael@0: "Dispatching event in nsShutdownThread::BlockingShutdown failed!"); michael@0: } else { michael@0: st->mCondVar.Wait(); michael@0: } michael@0: } michael@0: michael@0: return Shutdown(workerThread); michael@0: } michael@0: michael@0: NS_IMETHODIMP michael@0: nsShutdownThread::Run() michael@0: { michael@0: MutexAutoLock lock(mLock); michael@0: mThread->Shutdown(); michael@0: mCondVar.Notify(); michael@0: return NS_OK; michael@0: }