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 #ifndef mozjemalloc_utils_h
8 #define mozjemalloc_utils_h
11 #include <type_traits>
13 #if defined(MOZ_MEMORY) && defined(XP_WIN)
14 # include "mozmemory_wrap.h"
20 // Helper for StallAndRetry error messages.
22 constexpr bool is_std_optional
= false;
24 constexpr bool is_std_optional
<std::optional
<T
>> = true;
28 // Maximum number of retry-attempts before giving up.
30 // Delay time between successive events.
33 // Retry a fallible operation until it succeeds or until we've run out of
36 // Note that this invokes `aDelayFunc` immediately upon being called! It's
37 // intended for use in the unhappy path, after an initial attempt has failed.
39 // The function type here may be read:
41 // fn StallAndRetry<R>(
42 // delay_func: impl Fn(usize) -> (),
43 // operation: impl Fn() -> Option<R>,
47 template <typename DelayFunc
, typename OpFunc
>
48 auto StallAndRetry(DelayFunc
&& aDelayFunc
, OpFunc
&& aOperation
) const
49 -> decltype(aOperation()) {
51 // Explicit typecheck for OpFunc, to provide an explicit error message.
52 using detail::is_std_optional
;
53 static_assert(is_std_optional
<decltype(aOperation())>,
54 "aOperation() must return std::optional");
56 // (clang's existing error messages suffice for aDelayFunc.)
59 for (size_t i
= 0; i
< maxAttempts
; ++i
) {
61 if (const auto opt
= aOperation()) {
69 #if defined(MOZ_MEMORY) && defined(XP_WIN)
70 MOZ_JEMALLOC_API StallSpecs
GetAllocatorStallSpecs();
73 } // namespace mozilla
75 #endif // mozjemalloc_utils_h