MessagePortParent.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. /* -*- Mode: C++; tab-width: 2; 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
  4. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  5. #include "MessagePortParent.h"
  6. #include "MessagePortService.h"
  7. #include "SharedMessagePortMessage.h"
  8. #include "mozilla/Unused.h"
  9. namespace mozilla {
  10. namespace dom {
  11. MessagePortParent::MessagePortParent(const nsID& aUUID)
  12. : mService(MessagePortService::GetOrCreate())
  13. , mUUID(aUUID)
  14. , mEntangled(false)
  15. , mCanSendData(true)
  16. {
  17. MOZ_ASSERT(mService);
  18. }
  19. MessagePortParent::~MessagePortParent()
  20. {
  21. MOZ_ASSERT(!mService);
  22. MOZ_ASSERT(!mEntangled);
  23. }
  24. bool
  25. MessagePortParent::Entangle(const nsID& aDestinationUUID,
  26. const uint32_t& aSequenceID)
  27. {
  28. if (!mService) {
  29. NS_WARNING("Entangle is called after a shutdown!");
  30. return false;
  31. }
  32. MOZ_ASSERT(!mEntangled);
  33. return mService->RequestEntangling(this, aDestinationUUID, aSequenceID);
  34. }
  35. bool
  36. MessagePortParent::RecvPostMessages(nsTArray<MessagePortMessage>&& aMessages)
  37. {
  38. // This converts the object in a data struct where we have BlobImpls.
  39. FallibleTArray<RefPtr<SharedMessagePortMessage>> messages;
  40. if (NS_WARN_IF(
  41. !SharedMessagePortMessage::FromMessagesToSharedParent(aMessages,
  42. messages))) {
  43. return false;
  44. }
  45. if (!mEntangled) {
  46. return false;
  47. }
  48. if (!mService) {
  49. NS_WARNING("Entangle is called after a shutdown!");
  50. return false;
  51. }
  52. if (messages.IsEmpty()) {
  53. return false;
  54. }
  55. return mService->PostMessages(this, messages);
  56. }
  57. bool
  58. MessagePortParent::RecvDisentangle(nsTArray<MessagePortMessage>&& aMessages)
  59. {
  60. // This converts the object in a data struct where we have BlobImpls.
  61. FallibleTArray<RefPtr<SharedMessagePortMessage>> messages;
  62. if (NS_WARN_IF(
  63. !SharedMessagePortMessage::FromMessagesToSharedParent(aMessages,
  64. messages))) {
  65. return false;
  66. }
  67. if (!mEntangled) {
  68. return false;
  69. }
  70. if (!mService) {
  71. NS_WARNING("Entangle is called after a shutdown!");
  72. return false;
  73. }
  74. if (!mService->DisentanglePort(this, messages)) {
  75. return false;
  76. }
  77. CloseAndDelete();
  78. return true;
  79. }
  80. bool
  81. MessagePortParent::RecvStopSendingData()
  82. {
  83. if (!mEntangled) {
  84. return true;
  85. }
  86. mCanSendData = false;
  87. Unused << SendStopSendingDataConfirmed();
  88. return true;
  89. }
  90. bool
  91. MessagePortParent::RecvClose()
  92. {
  93. if (mService) {
  94. MOZ_ASSERT(mEntangled);
  95. if (!mService->ClosePort(this)) {
  96. return false;
  97. }
  98. Close();
  99. }
  100. MOZ_ASSERT(!mEntangled);
  101. Unused << Send__delete__(this);
  102. return true;
  103. }
  104. void
  105. MessagePortParent::ActorDestroy(ActorDestroyReason aWhy)
  106. {
  107. if (mService && mEntangled) {
  108. // When the last parent is deleted, this service is freed but this cannot
  109. // be done when the hashtables are written by CloseAll.
  110. RefPtr<MessagePortService> kungFuDeathGrip = mService;
  111. kungFuDeathGrip->ParentDestroy(this);
  112. }
  113. }
  114. bool
  115. MessagePortParent::Entangled(const nsTArray<MessagePortMessage>& aMessages)
  116. {
  117. MOZ_ASSERT(!mEntangled);
  118. mEntangled = true;
  119. return SendEntangled(aMessages);
  120. }
  121. void
  122. MessagePortParent::CloseAndDelete()
  123. {
  124. Close();
  125. Unused << Send__delete__(this);
  126. }
  127. void
  128. MessagePortParent::Close()
  129. {
  130. mService = nullptr;
  131. mEntangled = false;
  132. }
  133. /* static */ bool
  134. MessagePortParent::ForceClose(const nsID& aUUID,
  135. const nsID& aDestinationUUID,
  136. const uint32_t& aSequenceID)
  137. {
  138. MessagePortService* service = MessagePortService::Get();
  139. if (!service) {
  140. NS_WARNING("The service must exist if we want to close an existing MessagePort.");
  141. return false;
  142. }
  143. return service->ForceClose(aUUID, aDestinationUUID, aSequenceID);
  144. }
  145. } // namespace dom
  146. } // namespace mozilla