Line data Source code
1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* vim: set ts=2 et sw=2 tw=80: */
3 : /* This Source Code Form is subject to the terms of the Mozilla Public
4 : * License, v. 2.0. If a copy of the MPL was not distributed with this file,
5 : * You can obtain one at http://mozilla.org/MPL/2.0/. */
6 :
7 : #ifndef mozilla__CryptoTask_h
8 : #define mozilla__CryptoTask_h
9 :
10 : #include "mozilla/Attributes.h"
11 : #include "nsThreadUtils.h"
12 : #include "nsNSSShutDown.h"
13 :
14 : namespace mozilla {
15 :
16 : /**
17 : * Frequently we need to run a task on a background thread without blocking
18 : * the main thread, and then call a callback on the main thread with the
19 : * result. This class provides the framework for that. Subclasses must:
20 : *
21 : * (1) Override CalculateResult for the off-the-main-thread computation.
22 : * NSS functionality may only be accessed within CalculateResult.
23 : * (2) Override ReleaseNSSResources to release references to all NSS
24 : * resources (that do implement nsNSSShutDownObject themselves).
25 : * (3) Override CallCallback() for the on-the-main-thread call of the
26 : * callback.
27 : *
28 : * CalculateResult, ReleaseNSSResources, and CallCallback are called in order,
29 : * except CalculateResult might be skipped if NSS is shut down before it can
30 : * be called; in that case ReleaseNSSResources will be called and then
31 : * CallCallback will be called with an error code.
32 : *
33 : * That sequence of events is what happens if you call Dispatch. If for
34 : * some reason, you decide not to run the task (e.g., due to an error in the
35 : * constructor), you may call Skip, in which case the task is cleaned up and
36 : * not run. In that case, only ReleaseNSSResources is called. (So a
37 : * subclass must be prepared for ReleaseNSSResources to be run without
38 : * CalculateResult having been called first.)
39 : *
40 : * Once a CryptoTask is created, the calling code must call either
41 : * Dispatch or Skip.
42 : *
43 : */
44 : class CryptoTask : public Runnable,
45 : public nsNSSShutDownObject
46 : {
47 : public:
48 : template <size_t LEN>
49 0 : nsresult Dispatch(const char (&taskThreadName)[LEN])
50 : {
51 : static_assert(LEN <= 15,
52 : "Thread name must be no more than 15 characters");
53 0 : return Dispatch(nsDependentCString(taskThreadName, LEN - 1));
54 : }
55 :
56 : nsresult Dispatch(const nsACString& taskThreadName);
57 :
58 : void Skip()
59 : {
60 : virtualDestroyNSSReference();
61 : }
62 :
63 : protected:
64 0 : CryptoTask()
65 0 : : Runnable("CryptoTask")
66 : , mRv(NS_ERROR_NOT_INITIALIZED)
67 0 : , mReleasedNSSResources(false)
68 : {
69 0 : }
70 :
71 : virtual ~CryptoTask();
72 :
73 : /**
74 : * Called on a background thread (never the main thread). If CalculateResult
75 : * is called, then its result will be passed to CallCallback on the main
76 : * thread.
77 : */
78 : virtual nsresult CalculateResult() = 0;
79 :
80 : /**
81 : * Called on the main thread during NSS shutdown or just before CallCallback
82 : * has been called. All NSS resources must be released. Usually, this just
83 : * means assigning nullptr to the ScopedNSSType-based memory variables.
84 : */
85 : virtual void ReleaseNSSResources() = 0;
86 :
87 : /**
88 : * Called on the main thread with the result from CalculateResult() or
89 : * with an error code if NSS was shut down before CalculateResult could
90 : * be called.
91 : */
92 : virtual void CallCallback(nsresult rv) = 0;
93 :
94 : private:
95 : NS_IMETHOD Run() override final;
96 : virtual void virtualDestroyNSSReference() override final;
97 :
98 : nsresult mRv;
99 : bool mReleasedNSSResources;
100 :
101 : nsCOMPtr<nsIThread> mThread;
102 : };
103 :
104 : } // namespace mozilla
105 :
106 : #endif // mozilla__CryptoTask_h
|