blob: d7cbd870b252d21520a204b734e2ed2305f214b1 [file] [log] [blame]
// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <unittest/unittest.h>
#include <sched.h>
#include <threads.h>
#include "dso-ctor/dso-ctor.h"
namespace {
bool global_ctor_ran;
static struct Global {
Global() { global_ctor_ran = true; }
~Global() {
// This is just some random nonempty thing that the compiler
// can definitely never decide to optimize away. We can't
// easily test that the destructor got run, but we can ensure
// that using a static destructor compiles and links correctly.
sched_yield();
}
} global;
bool check_ctor() {
BEGIN_TEST;
EXPECT_TRUE(global_ctor_ran, "global constuctor didn't run!");
END_TEST;
}
int my_static = 23;
bool check_initializer() {
BEGIN_TEST;
EXPECT_EQ(my_static, 23, "static initializer didn't run!");
END_TEST;
}
bool tlocal_ctor_ran, tlocal_dtor_ran;
thread_local ThreadLocal<&tlocal_ctor_ran, &tlocal_dtor_ran> tlocal;
int do_thread_local_dtor_test(void*) {
BEGIN_HELPER;
EXPECT_TRUE(decltype(tlocal)::check_before_reference());
tlocal.flag = true;
EXPECT_TRUE(decltype(tlocal)::check_after_reference());
EXPECT_TRUE(check_dso_tlocal_in_thread());
END_HELPER;
}
bool check_thread_local_ctor_dtor() {
BEGIN_TEST;
thrd_t th;
ASSERT_EQ(thrd_create(&th, &do_thread_local_dtor_test, nullptr), thrd_success);
int retval = -1;
EXPECT_EQ(thrd_join(th, &retval), thrd_success);
EXPECT_TRUE(static_cast<bool>(retval));
EXPECT_TRUE(decltype(tlocal)::check_after_join());
EXPECT_TRUE(check_dso_tlocal_after_join());
END_TEST;
}
} // namespace
BEGIN_TEST_CASE(ctors)
RUN_TEST(check_ctor)
RUN_TEST(check_initializer)
RUN_TEST(check_dso_ctor)
RUN_TEST(check_thread_local_ctor_dtor)
END_TEST_CASE(ctors)