diff options
-rw-r--r-- | libc/private/ScopeGuard.h | 53 | ||||
-rw-r--r-- | tests/pthread_test.cpp | 12 |
2 files changed, 65 insertions, 0 deletions
diff --git a/libc/private/ScopeGuard.h b/libc/private/ScopeGuard.h new file mode 100644 index 0000000..183e322 --- /dev/null +++ b/libc/private/ScopeGuard.h @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SCOPE_GUARD_H +#define SCOPE_GUARD_H + +// TODO: include explicit std::move when it becomes available +template<typename F> +class ScopeGuard { + public: + ScopeGuard(F f) : f_(f), active_(true) {} + + ScopeGuard(ScopeGuard&& that) : f_(that.f_), active_(that.active_) { + that.active_ = false; + } + + ~ScopeGuard() { + if (active_) { + f_(); + } + } + + void disable() { + active_ = false; + } + private: + F f_; + bool active_; + + ScopeGuard() = delete; + ScopeGuard(const ScopeGuard&) = delete; + ScopeGuard& operator=(const ScopeGuard&) = delete; +}; + +template<typename T> +ScopeGuard<T> create_scope_guard(T f) { + return ScopeGuard<T>(f); +} + +#endif // SCOPE_GUARD_H diff --git a/tests/pthread_test.cpp b/tests/pthread_test.cpp index 6557738..4a7c6bd 100644 --- a/tests/pthread_test.cpp +++ b/tests/pthread_test.cpp @@ -27,6 +27,7 @@ #include <time.h> #include <unistd.h> +#include "private/ScopeGuard.h" #include "ScopedSignalHandler.h" TEST(pthread, pthread_key_create) { @@ -860,8 +861,19 @@ TEST(pthread, pthread_attr_getstack__main_thread) { // The stack size should correspond to RLIMIT_STACK. rlimit rl; ASSERT_EQ(0, getrlimit(RLIMIT_STACK, &rl)); + uint64_t original_rlim_cur = rl.rlim_cur; +#if defined(__BIONIC__) + if (rl.rlim_cur == RLIM_INFINITY) { + rl.rlim_cur = 8 * 1024 * 1024; // Bionic reports unlimited stacks as 8MiB. + } +#endif EXPECT_EQ(rl.rlim_cur, stack_size); + auto guard = create_scope_guard([&rl, original_rlim_cur]() { + rl.rlim_cur = original_rlim_cur; + ASSERT_EQ(0, setrlimit(RLIMIT_STACK, &rl)); + }); + // The high address of the /proc/self/maps [stack] region should equal stack_base + stack_size. // Remember that the stack grows down (and is mapped in on demand), so the low address of the // region isn't very interesting. |