From e9bcba4124189b6d53f46a6ac3b7ff67f5fd267b Mon Sep 17 00:00:00 2001 From: iivlev Date: Mon, 1 May 2017 09:26:04 +0300 Subject: [PATCH] Signal watcher functionality with test --- bindings/cpp/Makefile | 22 +++++++++++ bindings/cpp/include/wtf/posix_utils.h | 12 ++++++ bindings/cpp/posix_utils.cc | 53 ++++++++++++++++++++++++++ bindings/cpp/posix_utils_test.cc | 47 +++++++++++++++++++++++ 4 files changed, 134 insertions(+) create mode 100644 bindings/cpp/include/wtf/posix_utils.h create mode 100644 bindings/cpp/posix_utils.cc create mode 100644 bindings/cpp/posix_utils_test.cc diff --git a/bindings/cpp/Makefile b/bindings/cpp/Makefile index a0dfe002..707242b3 100644 --- a/bindings/cpp/Makefile +++ b/bindings/cpp/Makefile @@ -41,6 +41,10 @@ else $(error Expected value of THREADING to be single/pthread/std) endif +ifneq "$(THREADING)" "std" +override POSIX_SUPPORT = "0" +endif + # Required flag customizations. override CPPFLAGS += -Iinclude override CPPFLAGS += -I$(GTEST_DIR)/include @@ -67,6 +71,10 @@ PLATFORM_HEADERS := \ include/wtf/platform/platform_myriad2sparc_impl.h \ include/wtf/platform/platform_myriad2sparc_inl.h +ifeq "$(POSIX_SUPPORT)" "1" +LIBRARY_HEADERS += include/wtf/posix_utils.h +endif + ALL_HEADERS := $(LIBRARY_HEADERS) $(PLATFORM_HEADERS) LIBRARY_SOURCES := \ @@ -81,6 +89,11 @@ TEST_SOURCES := \ runtime_test.cc \ threaded_torture_test.cc +ifeq "$(POSIX_SUPPORT)" "1" +LIBRARY_SOURCES += posix_utils.cc +TEST_SOURCES += posix_utils_test.cc +endif + LIBRARY_OBJECTS := $(LIBRARY_SOURCES:%.cc=%.o) .PHONY: clean all test @@ -113,7 +126,13 @@ clean: $(wildcard tmp*.wtf-trace) ### TESTING. +ifneq "$(POSIX_SUPPORT)" "1" test: buffer_test macros_test runtime_test threaded_torture_test +else +test: buffer_test macros_test runtime_test threaded_torture_test posix_utils_test + @echo "Running posix_utils_test" + ./posix_utils_test +endif @echo "Running buffer_test" ./buffer_test @echo "Running macros_test" @@ -138,6 +157,9 @@ macros_test: macros_test.o gtest.o libwtf.a runtime_test: runtime_test.o gtest.o libwtf.a $(CXX) $(CXXFLAGS) $(CPPFLAGS) -o $@ $+ $(LDLIBS) +posix_utils_test: posix_utils_test.o gtest.o libwtf.a + $(CXX) $(CXXFLAGS) $(CPPFLAGS) -o $@ $+ $(LDLIBS) + ### THREADED TORTURE TEST ifneq "$(THREADING)" "single" threaded_torture_test: threaded_torture_test.o libwtf.a diff --git a/bindings/cpp/include/wtf/posix_utils.h b/bindings/cpp/include/wtf/posix_utils.h new file mode 100644 index 00000000..dbd4ef44 --- /dev/null +++ b/bindings/cpp/include/wtf/posix_utils.h @@ -0,0 +1,12 @@ +#ifndef POSIX_UTILS_H +#define POSIX_UTILS_H + +namespace wtf { +namespace posix_utils { + + void InstallSignalHandler(int number, char const* filename); + +} // namespace posix_utils +} // namespace wtf + +#endif // POSIX_UTILS_H diff --git a/bindings/cpp/posix_utils.cc b/bindings/cpp/posix_utils.cc new file mode 100644 index 00000000..69c5b4e5 --- /dev/null +++ b/bindings/cpp/posix_utils.cc @@ -0,0 +1,53 @@ +#include +#include + +#include +#include + +namespace { + +std::condition_variable gCv; +std::mutex gMutex; +std::string gFilename; + +void wtfOnSignal(int) { + gCv.notify_all(); +}; + +void wtfSignalWatcherThread () { + std::unique_lock lock { gMutex }; + while (true) { + gCv.wait(lock); + wtf::Runtime::GetInstance()->SaveToFile(gFilename.c_str()); + } +} + +} // namespace + +namespace wtf { +namespace posix_utils { + +void InstallSignalHandler(int number, char const* filename) { + if (!filename) { + fprintf(stderr, "%s: Error: filename can't be null\n", __PRETTY_FUNCTION__); + return; + } + + static bool onlyOnce = false; + if (onlyOnce) { + fprintf(stderr, "%s: Error: method be called only once per program execution.\n", __PRETTY_FUNCTION__); + return; + } + + onlyOnce = true; + + gFilename = filename; + std::thread thread { wtfSignalWatcherThread }; + + signal(number, wtfOnSignal); + + thread.detach(); +} + +} // namespace posix_utils +} // namespace wtf diff --git a/bindings/cpp/posix_utils_test.cc b/bindings/cpp/posix_utils_test.cc new file mode 100644 index 00000000..029b38ce --- /dev/null +++ b/bindings/cpp/posix_utils_test.cc @@ -0,0 +1,47 @@ +#include +#include + +#include "wtf/posix_utils.h" +#include "wtf/macros.h" + +#include "gtest/gtest.h" + +char const* kSignalWatcherFilename = "./tmptstsignal_watcher.wtf-trace"; + +namespace wtf { + +class PosixUtilsTest : public ::testing::Test { +protected: + void TearDown() override { + wtf::Runtime::GetInstance()->DisableCurrentThread(); + wtf::Runtime::GetInstance()->ResetForTesting(); + } + +}; + + +TEST_F(PosixUtilsTest, SignalWatcher) { + unlink(kSignalWatcherFilename); +// watch SIGALRM + wtf::posix_utils::InstallSignalHandler(14, kSignalWatcherFilename); + WTF_EVENT0("MacrosTest#SignalWatcher"); + + alarm(1); + + const int second = 1000; + usleep(5000 * second); + + alarm(0); +// allow the thread to finish it's work + usleep(1000 * second); + struct stat buffer; + + EXPECT_TRUE(stat(kSignalWatcherFilename, &buffer) == 0); + EXPECT_TRUE(buffer.st_size > 0); +} +} //namespace wtf + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +}