michael@0: /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* vim: set ts=2 et sw=2 tw=80: */ 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 file, michael@0: * You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef mozilla__CryptoTask_h michael@0: #define mozilla__CryptoTask_h michael@0: michael@0: #include "mozilla/Attributes.h" michael@0: #include "nsThreadUtils.h" michael@0: #include "nsNSSShutDown.h" michael@0: michael@0: namespace mozilla { michael@0: michael@0: /** michael@0: * Frequently we need to run a task on a background thread without blocking michael@0: * the main thread, and then call a callback on the main thread with the michael@0: * result. This class provides the framework for that. Subclasses must: michael@0: * michael@0: * (1) Override CalculateResult for the off-the-main-thread computation. michael@0: * NSS functionality may only be accessed within CalculateResult. michael@0: * (2) Override ReleaseNSSResources to release references to all NSS michael@0: * resources (that do implement nsNSSShutDownObject themselves). michael@0: * (3) Override CallCallback() for the on-the-main-thread call of the michael@0: * callback. michael@0: * michael@0: * CalculateResult, ReleaseNSSResources, and CallCallback are called in order, michael@0: * except CalculateResult might be skipped if NSS is shut down before it can michael@0: * be called; in that case ReleaseNSSResources will be called and then michael@0: * CallCallback will be called with an error code. michael@0: */ michael@0: class CryptoTask : public nsRunnable, michael@0: public nsNSSShutDownObject michael@0: { michael@0: public: michael@0: template michael@0: nsresult Dispatch(const char (&taskThreadName)[LEN]) michael@0: { michael@0: static_assert(LEN <= 15, michael@0: "Thread name must be no more than 15 characters"); michael@0: // Can't add 'this' as the event to run, since mThread may not be set yet michael@0: nsresult rv = NS_NewNamedThread(taskThreadName, getter_AddRefs(mThread)); michael@0: if (NS_SUCCEEDED(rv)) { michael@0: // Note: event must not null out mThread! michael@0: rv = mThread->Dispatch(this, NS_DISPATCH_NORMAL); michael@0: } michael@0: return rv; michael@0: } michael@0: michael@0: protected: michael@0: CryptoTask() michael@0: : mRv(NS_ERROR_NOT_INITIALIZED), michael@0: mReleasedNSSResources(false) michael@0: { michael@0: } michael@0: michael@0: virtual ~CryptoTask(); michael@0: michael@0: /** michael@0: * Called on a background thread (never the main thread). If CalculateResult michael@0: * is called, then its result will be passed to CallCallback on the main michael@0: * thread. michael@0: */ michael@0: virtual nsresult CalculateResult() = 0; michael@0: michael@0: /** michael@0: * Called on the main thread during NSS shutdown or just before CallCallback michael@0: * has been called. All NSS resources must be released. Usually, this just michael@0: * means assigning nullptr to the ScopedNSSType-based memory variables. michael@0: */ michael@0: virtual void ReleaseNSSResources() = 0; michael@0: michael@0: /** michael@0: * Called on the main thread with the result from CalculateResult() or michael@0: * with an error code if NSS was shut down before CalculateResult could michael@0: * be called. michael@0: */ michael@0: virtual void CallCallback(nsresult rv) = 0; michael@0: michael@0: private: michael@0: NS_IMETHOD Run() MOZ_OVERRIDE MOZ_FINAL; michael@0: virtual void virtualDestroyNSSReference() MOZ_OVERRIDE MOZ_FINAL; michael@0: michael@0: nsresult mRv; michael@0: bool mReleasedNSSResources; michael@0: michael@0: nsCOMPtr mThread; michael@0: }; michael@0: michael@0: } // namespace mozilla michael@0: michael@0: #endif // mozilla__CryptoTask_h