Skip to content
This repository was archived by the owner on Dec 29, 2022. It is now read-only.

Commit ef40415

Browse files
author
iivlev
committed
Signal watcher functionality with test
1 parent f35328f commit ef40415

8 files changed

+215
-0
lines changed

bindings/cpp/Makefile

+22
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ else
4141
$(error Expected value of THREADING to be single/pthread/std)
4242
endif
4343

44+
ifneq "$(THREADING)" "std"
45+
override POSIX_SUPPORT = "0"
46+
endif
47+
4448
# Required flag customizations.
4549
override CPPFLAGS += -Iinclude
4650
override CPPFLAGS += -I$(GTEST_DIR)/include
@@ -67,6 +71,10 @@ PLATFORM_HEADERS := \
6771
include/wtf/platform/platform_myriad2sparc_impl.h \
6872
include/wtf/platform/platform_myriad2sparc_inl.h
6973

74+
ifeq "$(POSIX_SUPPORT)" "1"
75+
LIBRARY_HEADERS += include/wtf/posix_utils.h
76+
endif
77+
7078
ALL_HEADERS := $(LIBRARY_HEADERS) $(PLATFORM_HEADERS)
7179

7280
LIBRARY_SOURCES := \
@@ -81,6 +89,11 @@ TEST_SOURCES := \
8189
runtime_test.cc \
8290
threaded_torture_test.cc
8391

92+
ifeq "$(POSIX_SUPPORT)" "1"
93+
LIBRARY_SOURCES += posix_utils.cc
94+
TEST_SOURCES += posix_utils_test.cc
95+
endif
96+
8497
LIBRARY_OBJECTS := $(LIBRARY_SOURCES:%.cc=%.o)
8598

8699
.PHONY: clean all test
@@ -113,7 +126,13 @@ clean:
113126
$(wildcard tmp*.wtf-trace)
114127

115128
### TESTING.
129+
ifneq "$(POSIX_SUPPORT)" "1"
116130
test: buffer_test macros_test runtime_test threaded_torture_test
131+
else
132+
test: buffer_test macros_test runtime_test threaded_torture_test posix_utils_test
133+
@echo "Running posix_utils_test"
134+
./posix_utils_test
135+
endif
117136
@echo "Running buffer_test"
118137
./buffer_test
119138
@echo "Running macros_test"
@@ -138,6 +157,9 @@ macros_test: macros_test.o gtest.o libwtf.a
138157
runtime_test: runtime_test.o gtest.o libwtf.a
139158
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -o $@ $+ $(LDLIBS)
140159

160+
posix_utils_test: posix_utils_test.o gtest.o libwtf.a
161+
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -o $@ $+ $(LDLIBS)
162+
141163
### THREADED TORTURE TEST
142164
ifneq "$(THREADING)" "single"
143165
threaded_torture_test: threaded_torture_test.o libwtf.a

bindings/cpp/include/wtf/macros.h

+36
Original file line numberDiff line numberDiff line change
@@ -154,4 +154,40 @@
154154
// Same as WTF_TASK_IF conditioned on the current namespace.
155155
#define WTF_TASK(name) WTF_TASK_IF(kWtfEnabledForNamespace, name)
156156

157+
#if defined(WTF_SINGLE_THREADED)
158+
159+
#include <signal.h>
160+
void __wtfOnSignal(int) {}
161+
#define WTF_INIT_SIGNAL_WATCHER(unused)
162+
#define WTF_WATCH_SIGNAL(number) do { signal(number, __wtfOnSignal); } while (false)
163+
164+
#else
165+
166+
#include <signal.h>
167+
168+
#define WTF_INIT_SIGNAL_WATCHER(filename) \
169+
__INTERNAL_WTF_NAMESPACE::platform::condition_variable __WTF_INTERNAL_UNIQUE(cv); \
170+
__INTERNAL_WTF_NAMESPACE::platform::mutex __WTF_INTERNAL_UNIQUE(mutex); \
171+
void __wtfOnSignal(int) { \
172+
__WTF_INTERNAL_UNIQUE(cv).notify_all(); \
173+
}; \
174+
void __wtfSignalWatcherThread () { \
175+
__INTERNAL_WTF_NAMESPACE::platform::unique_lock<__INTERNAL_WTF_NAMESPACE::platform::mutex> \
176+
lock { __WTF_INTERNAL_UNIQUE(mutex) }; \
177+
while (true) { \
178+
__WTF_INTERNAL_UNIQUE(cv).wait(lock); \
179+
__INTERNAL_WTF_NAMESPACE::Runtime::GetInstance()->SaveToFile(filename); \
180+
} \
181+
}
182+
183+
#define WTF_WATCH_SIGNAL(number) \
184+
__INTERNAL_WTF_NAMESPACE::platform::thread __WTF_INTERNAL_UNIQUE(thread) {__wtfSignalWatcherThread}; \
185+
do { \
186+
signal(number, __wtfOnSignal); \
187+
__WTF_INTERNAL_UNIQUE(thread).detach(); \
188+
} while(0)
189+
190+
#endif
191+
192+
157193
#endif // TRACING_FRAMEWORK_BINDINGS_CPP_INCLUDE_WTF_MACROS_H_

bindings/cpp/include/wtf/platform/platform_aux_pthreads_threaded_inl.h

+9
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66
#include <pthread.h>
77

88
#include <atomic>
9+
#include <condition_variable>
910
#include <mutex>
11+
#include <thread>
1012

1113
namespace wtf {
1214

@@ -17,9 +19,16 @@ using mutex = std::mutex;
1719
template <typename T>
1820
using lock_guard = std::lock_guard<T>;
1921

22+
template <typename T>
23+
using unique_lock = std::unique_lock<T>;
24+
2025
template <typename T>
2126
using atomic = std::atomic<T>;
2227

28+
using thread = std::thread;
29+
30+
using condition_variable = std::condition_variable;
31+
2332
// Since memory_order is an old-school enum, it needs to be imported
2433
// individually.
2534
using std::memory_order;

bindings/cpp/include/wtf/platform/platform_aux_std_threaded_inl.h

+8
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#define TRACING_FRAMEWORK_BINDINGS_CPP_INCLUDE_WTF_PLATFORM_AUX_STD_THREADED_INL_H_
66

77
#include <atomic>
8+
#include <condition_variable>
89
#include <mutex>
910
#include <thread>
1011

@@ -17,9 +18,16 @@ using mutex = std::mutex;
1718
template <typename T>
1819
using lock_guard = std::lock_guard<T>;
1920

21+
template <typename T>
22+
using unique_lock = std::unique_lock<T>;
23+
2024
template <typename T>
2125
using atomic = std::atomic<T>;
2226

27+
using thread = std::thread;
28+
29+
using condition_variable = std::condition_variable;
30+
2331
using once_flag = std::once_flag;
2432
template <class Callable>
2533
inline void call_once(once_flag& flag, Callable&& f) {
+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#ifndef POSIX_UTILS_H
2+
#define POSIX_UTILS_H
3+
4+
namespace wtf {
5+
namespace posix_utils {
6+
7+
void InstallSignalHandler(int number, char const* filename);
8+
9+
} // namespace posix_utils
10+
} // namespace wtf
11+
12+
#endif // POSIX_UTILS_H

bindings/cpp/macros_test.cc

+31
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,19 @@
11
#include "wtf/macros.h"
22

33
#include <fstream>
4+
#include <unistd.h>
5+
#include <sys/stat.h>
46

57
#include "gtest/gtest.h"
68

79
#ifndef TMP_PREFIX
810
#define TMP_PREFIX ""
911
#endif
1012

13+
char const* kSignalWatcherFilename = "./tmptstsignal_watcher.wtf-trace";
14+
15+
WTF_INIT_SIGNAL_WATCHER(kSignalWatcherFilename);
16+
1117
namespace wtf {
1218
namespace {
1319

@@ -231,6 +237,31 @@ TEST_F(MacrosTest, BasicEndToEnd) {
231237
Runtime::GetInstance()->SaveToFile(TMP_PREFIX "tmpmacrobuf.wtf-trace"));
232238
}
233239

240+
TEST_F(MacrosTest, SignalWatcher) {
241+
ClearEventBuffer();
242+
unlink(kSignalWatcherFilename);
243+
// watch SIGALRM
244+
WTF_WATCH_SIGNAL(14);
245+
WTF_EVENT0("MacrosTest#SignalWatcher");
246+
247+
alarm(1);
248+
249+
const int second = 1000;
250+
usleep(5000 * second);
251+
252+
alarm(0);
253+
// allow the thread to finish it's work
254+
usleep(1000 * second);
255+
struct stat buffer;
256+
257+
#if defined(WTF_SINGLE_THREADED)
258+
EXPECT_FALSE(stat(kSignalWatcherFilename, &buffer) == 0);
259+
#else
260+
EXPECT_TRUE(stat(kSignalWatcherFilename, &buffer) == 0);
261+
EXPECT_TRUE(buffer.st_size > 0);
262+
#endif
263+
}
264+
234265
} // namespace
235266
} // namespace wtf
236267

bindings/cpp/posix_utils.cc

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
#include <wtf/runtime.h>
2+
#include <signal.h>
3+
4+
namespace {
5+
6+
std::condition_variable gCv;
7+
std::mutex gMutex;
8+
std::string gFilename;
9+
10+
void wtfOnSignal(int) {
11+
gCv.notify_all();
12+
};
13+
14+
void wtfSignalWatcherThread () {
15+
std::unique_lock<std::mutex> lock { gMutex };
16+
while (true) {
17+
gCv.wait(lock);
18+
wtf::Runtime::GetInstance()->SaveToFile(gFilename.c_str());
19+
}
20+
}
21+
22+
} // namespace
23+
24+
namespace wtf {
25+
namespace posix_utils {
26+
27+
void InstallSignalHandler(int number, char const* filename) {
28+
if (!filename) {
29+
fprintf(stderr, "%s: Error: filename can't be null\n", __PRETTY_FUNCTION__);
30+
return;
31+
}
32+
33+
static bool onlyOnce {false}:
34+
if (onlyOnce) {
35+
fprintf(stderr, "%s: Error: method be called only once per program execution.\n", __PRETTY_FUNCTION__);
36+
return;
37+
}
38+
39+
onlyOnce = true;
40+
41+
gFilename = filename;
42+
std::thread thread { wtfSignalWatcherThread };
43+
44+
signal(number, wtfOnSignal);
45+
46+
thread.detach();
47+
}
48+
49+
} // namespace posix_utils
50+
} // namespace wtf

bindings/cpp/posix_utils_test.cc

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#include <unistd.h>
2+
#include <sys/stat.h>
3+
4+
#include "wtf/posix_utils.h"
5+
#include "wtf/macros.h"
6+
7+
#include "gtest/gtest.h"
8+
9+
char const* kSignalWatcherFilename = "./tmptstsignal_watcher.wtf-trace";
10+
11+
namespace wtf {
12+
13+
class PosixUtilsTest : public ::testing::Test {
14+
protected:
15+
void TearDown() override {
16+
wtf::Runtime::GetInstance()->DisableCurrentThread();
17+
wtf::Runtime::GetInstance()->ResetForTesting();
18+
}
19+
20+
};
21+
22+
23+
TEST_F(PosixUtilsTest, SignalWatcher) {
24+
unlink(kSignalWatcherFilename);
25+
// watch SIGALRM
26+
wtf::posix_utils::InstallSignalHandler(14, kSignalWatcherFilename);
27+
WTF_EVENT0("MacrosTest#SignalWatcher");
28+
29+
alarm(1);
30+
31+
const int second = 1000;
32+
usleep(5000 * second);
33+
34+
alarm(0);
35+
// allow the thread to finish it's work
36+
usleep(1000 * second);
37+
struct stat buffer;
38+
39+
EXPECT_TRUE(stat(kSignalWatcherFilename, &buffer) == 0);
40+
EXPECT_TRUE(buffer.st_size > 0);
41+
}
42+
} //namespace wtf
43+
44+
int main(int argc, char** argv) {
45+
::testing::InitGoogleTest(&argc, argv);
46+
return RUN_ALL_TESTS();
47+
}

0 commit comments

Comments
 (0)