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"
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
;
20 already_AddRefed
<RefMessageBodyService
> RefMessageBodyService::GetOrCreate() {
21 StaticMutexAutoLock
lock(sRefMessageBodyServiceMutex
);
23 RefPtr
<RefMessageBodyService
> service
= GetOrCreateInternal(lock
);
24 return service
.forget();
28 RefMessageBodyService
* RefMessageBodyService::GetOrCreateInternal(
29 const StaticMutexAutoLock
& aProofOfLock
) {
31 sService
= new RefMessageBodyService();
36 RefMessageBodyService::RefMessageBodyService() {
37 MOZ_DIAGNOSTIC_ASSERT(sService
== nullptr);
40 RefMessageBodyService::~RefMessageBodyService() {
41 MOZ_DIAGNOSTIC_ASSERT(sService
== this);
45 const nsID
RefMessageBodyService::Register(
46 already_AddRefed
<RefMessageBody
> aBody
, ErrorResult
& aRv
) {
47 RefPtr
<RefMessageBody
> body
= aBody
;
51 aRv
= nsContentUtils::GenerateUUIDInPlace(uuid
);
52 if (NS_WARN_IF(aRv
.Failed())) {
56 StaticMutexAutoLock
lock(sRefMessageBodyServiceMutex
);
57 GetOrCreateInternal(lock
)->mMessages
.Put(uuid
, std::move(body
));
61 already_AddRefed
<RefMessageBody
> RefMessageBodyService::Steal(const nsID
& aID
) {
62 StaticMutexAutoLock
lock(sRefMessageBodyServiceMutex
);
67 RefPtr
<RefMessageBody
> body
;
68 sService
->mMessages
.Remove(aID
, getter_AddRefs(body
));
73 already_AddRefed
<RefMessageBody
> RefMessageBodyService::GetAndCount(
75 StaticMutexAutoLock
lock(sRefMessageBodyServiceMutex
);
80 RefPtr
<RefMessageBody
> body
= sService
->mMessages
.Get(aID
);
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
);
96 void RefMessageBodyService::SetMaxCount(const nsID
& aID
, uint32_t aMaxCount
) {
97 StaticMutexAutoLock
lock(sRefMessageBodyServiceMutex
);
102 RefPtr
<RefMessageBody
> body
= sService
->mMessages
.Get(aID
);
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
);
122 for (auto iter
= sService
->mMessages
.ConstIter(); !iter
.Done(); iter
.Next()) {
123 if (iter
.UserData()->PortID() == aPortID
) {
130 } // namespace mozilla