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 "mozilla/rlbox/rlbox_config.h"
13 # include "mozilla/rlbox/rlbox_wasm2c_sandbox.hpp"
16 using namespace mozilla
;
18 NS_IMPL_ISUPPORTS(RLBoxSandboxPool
, nsITimerCallback
, nsINamed
)
20 void RLBoxSandboxPool::StartTimer() {
21 mMutex
.AssertCurrentThreadOwns();
22 MOZ_ASSERT(!mTimer
, "timer already initialized");
23 if (NS_IsMainThread() &&
24 PastShutdownPhase(ShutdownPhase::AppShutdownConfirmed
)) {
25 // If we're shutting down, setting the time might fail, and we don't need it
26 // (since all the memory will be cleaned up soon anyway). Note that
27 // PastShutdownPhase() can only be called on the main thread, but that's
28 // fine, because other threads will have joined already by the point timers
29 // start failing to register.
33 DebugOnly
<nsresult
> rv
= NS_NewTimerWithCallback(
34 getter_AddRefs(mTimer
), this, mDelaySeconds
* 1000,
35 nsITimer::TYPE_ONE_SHOT
, GetMainThreadSerialEventTarget());
36 MOZ_ASSERT(NS_SUCCEEDED(rv
), "failed to create timer");
39 void RLBoxSandboxPool::CancelTimer() {
40 mMutex
.AssertCurrentThreadOwns();
47 NS_IMETHODIMP
RLBoxSandboxPool::Notify(nsITimer
* aTimer
) {
48 MutexAutoLock
lock(mMutex
);
56 NS_IMETHODIMP
RLBoxSandboxPool::GetName(nsACString
& aName
) {
57 aName
.AssignLiteral("RLBoxSandboxPool");
61 void RLBoxSandboxPool::Push(UniquePtr
<RLBoxSandboxDataBase
> sbxData
) {
62 MutexAutoLock
lock(mMutex
);
64 mPool
.AppendElement(std::move(sbxData
));
70 UniquePtr
<RLBoxSandboxPoolData
> RLBoxSandboxPool::PopOrCreate(
72 MutexAutoLock
lock(mMutex
);
74 UniquePtr
<RLBoxSandboxDataBase
> sbxData
;
76 if (!mPool
.IsEmpty()) {
77 const int64_t lastIndex
= ReleaseAssertedCast
<int64_t>(mPool
.Length()) - 1;
78 for (int64_t i
= lastIndex
; i
>= 0; i
--) {
79 if (mPool
[i
]->mSize
>= aMinSize
) {
80 sbxData
= std::move(mPool
[i
]);
81 mPool
.RemoveElementAt(i
);
83 // If we reuse a sandbox from the pool, reset the timer to clear the
86 if (!mPool
.IsEmpty()) {
95 #ifdef MOZ_USING_WASM_SANDBOXING
96 // RLBox's wasm sandboxes have a limited platform dependent capacity. We
97 // track this capacity in this pool. Note the noop sandboxes have no
98 // capacity limit but this design assumes that all sandboxes use the wasm
100 const uint64_t defaultCapacityForSandbox
=
101 wasm_rt_get_default_max_linear_memory_size();
102 const uint64_t minSandboxCapacity
=
103 std::max(aMinSize
, defaultCapacityForSandbox
);
104 const uint64_t chosenAdjustedCapacity
=
105 rlbox::rlbox_wasm2c_sandbox::rlbox_wasm2c_get_adjusted_heap_size(
108 // If sandboxing is disabled altogether we just set a limit of 4gb.
109 // This is not actually enforced by the noop sandbox.
110 const uint64_t chosenAdjustedCapacity
= static_cast<uint64_t>(1) << 32;
112 sbxData
= CreateSandboxData(chosenAdjustedCapacity
);
113 NS_ENSURE_TRUE(sbxData
, nullptr);
116 return MakeUnique
<RLBoxSandboxPoolData
>(std::move(sbxData
), this);