Bug 1634779 - pt 2. Partially revert Bug 1603006 r=kmag
[gecko.git] / dom / ipc / RefMessageBodyService.cpp
bloba9f8683599d0a23484679512cdb92f02311036e6
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=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
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "RefMessageBodyService.h"
8 #include "nsContentUtils.h"
10 namespace mozilla {
11 namespace dom {
13 StaticMutex sRefMessageBodyServiceMutex;
15 // Raw pointer because the service is kept alive by other objects.
16 // See the CTOR and the DTOR of this object.
17 RefMessageBodyService* sService;
19 // static
20 already_AddRefed<RefMessageBodyService> RefMessageBodyService::GetOrCreate() {
21 StaticMutexAutoLock lock(sRefMessageBodyServiceMutex);
23 RefPtr<RefMessageBodyService> service = GetOrCreateInternal(lock);
24 return service.forget();
27 // static
28 RefMessageBodyService* RefMessageBodyService::GetOrCreateInternal(
29 const StaticMutexAutoLock& aProofOfLock) {
30 if (!sService) {
31 sService = new RefMessageBodyService();
33 return sService;
36 RefMessageBodyService::RefMessageBodyService() {
37 MOZ_DIAGNOSTIC_ASSERT(sService == nullptr);
40 RefMessageBodyService::~RefMessageBodyService() {
41 MOZ_DIAGNOSTIC_ASSERT(sService == this);
42 sService = nullptr;
45 const nsID RefMessageBodyService::Register(
46 already_AddRefed<RefMessageBody> aBody, ErrorResult& aRv) {
47 RefPtr<RefMessageBody> body = aBody;
48 MOZ_ASSERT(body);
50 nsID uuid = {};
51 aRv = nsContentUtils::GenerateUUIDInPlace(uuid);
52 if (NS_WARN_IF(aRv.Failed())) {
53 return nsID();
56 StaticMutexAutoLock lock(sRefMessageBodyServiceMutex);
57 GetOrCreateInternal(lock)->mMessages.Put(uuid, std::move(body));
58 return uuid;
61 already_AddRefed<RefMessageBody> RefMessageBodyService::Steal(const nsID& aID) {
62 StaticMutexAutoLock lock(sRefMessageBodyServiceMutex);
63 if (!sService) {
64 return nullptr;
67 RefPtr<RefMessageBody> body;
68 sService->mMessages.Remove(aID, getter_AddRefs(body));
70 return body.forget();
73 already_AddRefed<RefMessageBody> RefMessageBodyService::GetAndCount(
74 const nsID& aID) {
75 StaticMutexAutoLock lock(sRefMessageBodyServiceMutex);
76 if (!sService) {
77 return nullptr;
80 RefPtr<RefMessageBody> body = sService->mMessages.Get(aID);
81 if (!body) {
82 return nullptr;
85 ++body->mCount;
87 MOZ_ASSERT_IF(body->mMaxCount.isSome(),
88 body->mCount <= body->mMaxCount.value());
89 if (body->mMaxCount.isSome() && body->mCount >= body->mMaxCount.value()) {
90 sService->mMessages.Remove(aID);
93 return body.forget();
96 void RefMessageBodyService::SetMaxCount(const nsID& aID, uint32_t aMaxCount) {
97 StaticMutexAutoLock lock(sRefMessageBodyServiceMutex);
98 if (!sService) {
99 return;
102 RefPtr<RefMessageBody> body = sService->mMessages.Get(aID);
103 if (!body) {
104 return;
107 MOZ_ASSERT(body->mMaxCount.isNothing());
108 body->mMaxCount.emplace(aMaxCount);
110 MOZ_ASSERT(body->mCount <= body->mMaxCount.value());
111 if (body->mCount >= body->mMaxCount.value()) {
112 sService->mMessages.Remove(aID);
116 void RefMessageBodyService::ForgetPort(const nsID& aPortID) {
117 StaticMutexAutoLock lock(sRefMessageBodyServiceMutex);
118 if (!sService) {
119 return;
122 for (auto iter = sService->mMessages.ConstIter(); !iter.Done(); iter.Next()) {
123 if (iter.UserData()->PortID() == aPortID) {
124 iter.Remove();
129 } // namespace dom
130 } // namespace mozilla