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 "nsThreadUtils.h"
8 #include "mozilla/ClearOnShutdown.h"
9 #include "mozilla/DebugOnly.h"
10 #include "mozilla/RLBoxSandboxPool.h"
11 #ifdef MOZ_USING_WASM_SANDBOXING
12 # include "wasm2c_rt_mem.h"
15 using namespace mozilla
;
17 NS_IMPL_ISUPPORTS(RLBoxSandboxPool
, nsITimerCallback
, nsINamed
)
19 void RLBoxSandboxPool::StartTimer() {
20 mMutex
.AssertCurrentThreadOwns();
21 MOZ_ASSERT(!mTimer
, "timer already initialized");
22 if (NS_IsMainThread() &&
23 PastShutdownPhase(ShutdownPhase::AppShutdownConfirmed
)) {
24 // If we're shutting down, setting the time might fail, and we don't need it
25 // (since all the memory will be cleaned up soon anyway). Note that
26 // PastShutdownPhase() can only be called on the main thread, but that's
27 // fine, because other threads will have joined already by the point timers
28 // start failing to register.
32 DebugOnly
<nsresult
> rv
= NS_NewTimerWithCallback(
33 getter_AddRefs(mTimer
), this, mDelaySeconds
* 1000,
34 nsITimer::TYPE_ONE_SHOT
, GetMainThreadSerialEventTarget());
35 MOZ_ASSERT(NS_SUCCEEDED(rv
), "failed to create timer");
38 void RLBoxSandboxPool::CancelTimer() {
39 mMutex
.AssertCurrentThreadOwns();
46 NS_IMETHODIMP
RLBoxSandboxPool::Notify(nsITimer
* aTimer
) {
47 MutexAutoLock
lock(mMutex
);
55 NS_IMETHODIMP
RLBoxSandboxPool::GetName(nsACString
& aName
) {
56 aName
.AssignLiteral("RLBoxSandboxPool");
60 void RLBoxSandboxPool::Push(UniquePtr
<RLBoxSandboxDataBase
> sbxData
) {
61 MutexAutoLock
lock(mMutex
);
63 mPool
.AppendElement(std::move(sbxData
));
69 UniquePtr
<RLBoxSandboxPoolData
> RLBoxSandboxPool::PopOrCreate(
71 MutexAutoLock
lock(mMutex
);
73 UniquePtr
<RLBoxSandboxDataBase
> sbxData
;
75 if (!mPool
.IsEmpty()) {
76 const int64_t lastIndex
= ReleaseAssertedCast
<int64_t>(mPool
.Length()) - 1;
77 for (int64_t i
= lastIndex
; i
>= 0; i
--) {
78 if (mPool
[i
]->mSize
>= aMinSize
) {
79 sbxData
= std::move(mPool
[i
]);
80 mPool
.RemoveElementAt(i
);
82 // If we reuse a sandbox from the pool, reset the timer to clear the
85 if (!mPool
.IsEmpty()) {
94 #ifdef MOZ_USING_WASM_SANDBOXING
95 // RLBox's wasm sandboxes have a limited platform dependent capacity. We
96 // track this capacity in this pool.
97 const w2c_mem_capacity w2c_capacity
= get_valid_wasm2c_memory_capacity(
98 aMinSize
, true /* 32-bit wasm memory*/);
99 const uint64_t chosenCapacity
= w2c_capacity
.max_size
;
101 // Note the noop sandboxes have no capacity limit. In this case we simply
102 // specify a value of 4gb. This is not actually enforced by the noop
104 const uint64_t chosenCapacity
= static_cast<uint64_t>(1) << 32;
106 sbxData
= CreateSandboxData(chosenCapacity
);
107 NS_ENSURE_TRUE(sbxData
, nullptr);
110 return MakeUnique
<RLBoxSandboxPoolData
>(std::move(sbxData
), this);