Skip to content

Commit 2aec857

Browse files
committed
Make it not do those segfault thingies
1 parent c1af105 commit 2aec857

File tree

2 files changed

+40
-39
lines changed

2 files changed

+40
-39
lines changed

collector/lib/Pipeline.h

Lines changed: 34 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#ifndef _COLLECTOR_PIPELINE_H
22
#define _COLLECTOR_PIPELINE_H
33

4+
#include <chrono>
5+
#include <condition_variable>
46
#include <memory>
57
#include <mutex>
68
#include <optional>
@@ -17,16 +19,6 @@ class Queue {
1719
Queue() {}
1820
~Queue() {}
1921

20-
T front() {
21-
auto lock = read_lock();
22-
return inner_.front();
23-
}
24-
25-
T back() {
26-
auto lock = read_lock();
27-
return inner_.back();
28-
}
29-
3022
bool empty() {
3123
auto lock = read_lock();
3224
return inner_.empty();
@@ -38,34 +30,36 @@ class Queue {
3830
}
3931

4032
void push(const T& elem) {
41-
auto lock = write_lock();
42-
auto e = elem;
43-
inner_.push(std::move(e));
33+
{
34+
auto lock = write_lock();
35+
auto e = elem;
36+
inner_.push(std::move(e));
37+
}
4438
state_changed_.notify_one();
4539
}
4640

4741
void push(T&& elem) {
48-
auto lock = write_lock();
49-
inner_.push(elem);
42+
{
43+
auto lock = write_lock();
44+
inner_.push(elem);
45+
}
5046
state_changed_.notify_one();
5147
}
5248

53-
template <class... Args>
54-
decltype(auto) emplace(Args&&... args) {
49+
std::optional<T> pop(std::chrono::milliseconds wait_max = std::chrono::milliseconds(10)) {
5550
auto lock = write_lock();
56-
decltype(auto) out = inner_.emplace(std::forward<Args>(args)...);
57-
state_changed_.notify_one();
58-
return out;
59-
}
51+
if (inner_.empty()) {
52+
auto pred = [this]() {
53+
return !inner_.empty();
54+
};
6055

61-
T pop() {
62-
auto lock = write_lock();
63-
if (empty()) {
64-
state_changed_.wait(lock, [this]() { return empty(); });
56+
if (!state_changed_.wait_for(lock, wait_max, pred)) {
57+
return std::nullopt;
58+
}
6559
}
6660
T data = inner_.front();
6761
inner_.pop();
68-
return data;
62+
return {data};
6963
}
7064

7165
std::shared_lock<std::shared_mutex> read_lock() const {
@@ -94,7 +88,7 @@ class Producer {
9488
}
9589
}
9690

97-
virtual T next() = 0;
91+
virtual std::optional<T> next() = 0;
9892

9993
void Start() {
10094
thread_.Start([this] { Run(); });
@@ -107,7 +101,10 @@ class Producer {
107101
void Run() {
108102
while (!thread_.should_stop()) {
109103
auto event = next();
110-
output_->push(event);
104+
if (!event.has_value()) {
105+
break;
106+
}
107+
output_->push(event.value());
111108
}
112109
}
113110

@@ -140,7 +137,10 @@ class Consumer {
140137
void Run() {
141138
while (!thread_.should_stop()) {
142139
auto event = input_->pop();
143-
handle(event);
140+
if (!event.has_value()) {
141+
continue;
142+
}
143+
handle(event.value());
144144
}
145145
}
146146

@@ -170,7 +170,11 @@ class Transformer {
170170
void Run() {
171171
while (!thread_.should_stop()) {
172172
auto event = input_->pop();
173-
auto transformed = transform(event);
173+
if (!event.has_value()) {
174+
continue;
175+
}
176+
177+
auto transformed = transform(event.value());
174178
if (transformed.has_value()) {
175179
output_.push(transformed.value());
176180
}

collector/test/PipelineTests.cpp

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#include <chrono>
22
#include <memory>
3+
#include <optional>
34
#include <ratio>
45
#include <thread>
56
#include <vector>
@@ -14,12 +15,12 @@ class IntProducer : public Producer<int> {
1415
public:
1516
IntProducer(std::shared_ptr<Queue<int>>& input, int limit) : Producer(input), limit_(limit) {}
1617

17-
int next() override {
18+
std::optional<int> next() override {
1819
n_++;
1920
if (n_ > limit_) {
20-
return limit_;
21+
return std::nullopt;
2122
}
22-
return n_;
23+
return {n_};
2324
}
2425

2526
private:
@@ -29,18 +30,14 @@ class IntProducer : public Producer<int> {
2930

3031
class IntConsumer : public Consumer<int> {
3132
public:
32-
IntConsumer(std::shared_ptr<Queue<int>>& input, std::vector<int> output) : Consumer(input), events_(output) {}
33+
IntConsumer(std::shared_ptr<Queue<int>>& input, std::vector<int>& output) : Consumer(input), events_(output) {}
3334

3435
void handle(const int& event) override {
3536
events_.push_back(event);
3637
}
3738

38-
std::vector<int>& Events() {
39-
return events_;
40-
}
41-
4239
private:
43-
std::vector<int> events_;
40+
std::vector<int>& events_;
4441
};
4542

4643
class EvenIntFilter : public Filter<int> {

0 commit comments

Comments
 (0)