-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy paththread_safe_object_test.cpp
71 lines (60 loc) · 1.92 KB
/
thread_safe_object_test.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#include <houseguest/thread_safe_object.hpp>
#include <algorithm>
#include <future>
#include <thread>
#include <vector>
#include <gtest/gtest.h>
#include <houseguest/synchronize.hpp>
TEST(ThreadSafeObject, default_ctor) // NOLINT
{
houseguest::threadsafe_object<std::vector<int>> tsv;
auto handle = tsv.read();
ASSERT_TRUE(handle->empty());
ASSERT_EQ(0, handle->size());
}
TEST(ThreadSafeObject, args_ctor) // NOLINT
{
houseguest::threadsafe_object<std::vector<int>> tsv{10};
auto handle = tsv.read();
ASSERT_FALSE(handle->empty());
ASSERT_EQ(1, handle->size());
}
TEST(ThreadSafeObject, write_handle) // NOLINT
{
houseguest::threadsafe_object<std::vector<int>> tsv;
auto handle = tsv.write();
handle->push_back(10);
ASSERT_FALSE(handle->empty());
ASSERT_EQ(1, handle->size());
}
TEST(ThreadSafeObject, multi_thread_read) // NOLINT
{
houseguest::threadsafe_object<int> tsi;
std::mutex m;
auto make_thread_fn = [&m, &tsi](auto & local_promise, auto & local_cv) {
return [&tsi, &m, &local_promise, &local_cv]() {
auto handle = tsi.read();
houseguest::synchronize_unique(
m, [&local_promise, &local_cv](auto lock) {
local_promise.set_value();
local_cv.wait(lock);
});
};
};
houseguest::synchronize_unique(m, [&make_thread_fn](auto lock) {
std::promise<void> p1;
std::promise<void> p2;
std::condition_variable c1;
std::condition_variable c2;
std::thread ts[] = {std::thread{make_thread_fn(p1, c1)},
std::thread{make_thread_fn(p2, c2)}};
lock.unlock();
p1.get_future().get();
p2.get_future().get();
lock.lock();
c1.notify_one();
c2.notify_one();
lock.unlock();
std::for_each(std::begin(ts), std::end(ts), [](auto & t) { t.join(); });
});
}