CryptoTask.cpp 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
  2. /* This Source Code Form is subject to the terms of the Mozilla Public
  3. * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  4. * You can obtain one at http://mozilla.org/MPL/2.0/. */
  5. #include "CryptoTask.h"
  6. #include "nsNSSComponent.h"
  7. namespace mozilla {
  8. CryptoTask::~CryptoTask()
  9. {
  10. MOZ_ASSERT(mReleasedNSSResources);
  11. nsNSSShutDownPreventionLock lock;
  12. if (!isAlreadyShutDown()) {
  13. shutdown(ShutdownCalledFrom::Object);
  14. }
  15. }
  16. nsresult
  17. CryptoTask::Dispatch(const nsACString& taskThreadName)
  18. {
  19. MOZ_ASSERT(taskThreadName.Length() <= 15);
  20. // Ensure that NSS is initialized, since presumably CalculateResult
  21. // will use NSS functions
  22. if (!EnsureNSSInitializedChromeOrContent()) {
  23. return NS_ERROR_FAILURE;
  24. }
  25. // Can't add 'this' as the event to run, since mThread may not be set yet
  26. nsresult rv = NS_NewThread(getter_AddRefs(mThread), nullptr,
  27. nsIThreadManager::DEFAULT_STACK_SIZE);
  28. if (NS_FAILED(rv)) {
  29. return rv;
  30. }
  31. NS_SetThreadName(mThread, taskThreadName);
  32. // Note: event must not null out mThread!
  33. return mThread->Dispatch(this, NS_DISPATCH_NORMAL);
  34. }
  35. NS_IMETHODIMP
  36. CryptoTask::Run()
  37. {
  38. if (!NS_IsMainThread()) {
  39. nsNSSShutDownPreventionLock locker;
  40. if (isAlreadyShutDown()) {
  41. mRv = NS_ERROR_NOT_AVAILABLE;
  42. } else {
  43. mRv = CalculateResult();
  44. }
  45. NS_DispatchToMainThread(this);
  46. } else {
  47. // back on the main thread
  48. // call ReleaseNSSResources now, before calling CallCallback, so that
  49. // CryptoTasks have consistent behavior regardless of whether NSS is shut
  50. // down between CalculateResult being called and CallCallback being called.
  51. if (!mReleasedNSSResources) {
  52. mReleasedNSSResources = true;
  53. ReleaseNSSResources();
  54. }
  55. CallCallback(mRv);
  56. // Not all uses of CryptoTask use a transient thread
  57. if (mThread) {
  58. // Don't leak threads!
  59. mThread->Shutdown(); // can't Shutdown from the thread itself, darn
  60. // Don't null out mThread!
  61. // See bug 999104. We must hold a ref to the thread across Dispatch()
  62. // since the internal mThread ref could be released while processing
  63. // the Dispatch(), and Dispatch/PutEvent itself doesn't hold a ref; it
  64. // assumes the caller does.
  65. }
  66. }
  67. return NS_OK;
  68. }
  69. void
  70. CryptoTask::virtualDestroyNSSReference()
  71. {
  72. MOZ_ASSERT(NS_IsMainThread(),
  73. "virtualDestroyNSSReference called off the main thread");
  74. if (!mReleasedNSSResources) {
  75. mReleasedNSSResources = true;
  76. ReleaseNSSResources();
  77. }
  78. }
  79. } // namespace mozilla