mirror of https://github.com/procxx/kepka.git
Fix reading from freed memory in rpl::take().
This commit is contained in:
parent
583b0fa778
commit
6445c0563e
|
@ -329,6 +329,11 @@ public:
|
||||||
Type *make_state(Args&& ...args) const;
|
Type *make_state(Args&& ...args) const;
|
||||||
|
|
||||||
void terminate() const;
|
void terminate() const;
|
||||||
|
auto terminator() const {
|
||||||
|
return [self = *this] {
|
||||||
|
self.terminate();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
const details::type_erased_handlers<Value, Error> *comparable() const {
|
const details::type_erased_handlers<Value, Error> *comparable() const {
|
||||||
return _handlers.get();
|
return _handlers.get();
|
||||||
|
|
|
@ -44,7 +44,7 @@ public:
|
||||||
[consumer, state](producer<Value, Error> &&inner) {
|
[consumer, state](producer<Value, Error> &&inner) {
|
||||||
state->finished = false;
|
state->finished = false;
|
||||||
state->alive = lifetime();
|
state->alive = lifetime();
|
||||||
auto started = std::move(inner).start(
|
std::move(inner).start(
|
||||||
[consumer](auto &&value) {
|
[consumer](auto &&value) {
|
||||||
consumer.put_next_forward(std::forward<decltype(value)>(value));
|
consumer.put_next_forward(std::forward<decltype(value)>(value));
|
||||||
}, [consumer](auto &&error) {
|
}, [consumer](auto &&error) {
|
||||||
|
@ -55,10 +55,7 @@ public:
|
||||||
} else {
|
} else {
|
||||||
state->finished = true;
|
state->finished = true;
|
||||||
}
|
}
|
||||||
});
|
}, state->alive);
|
||||||
if (started) {
|
|
||||||
state->alive = std::move(started);
|
|
||||||
}
|
|
||||||
}, [consumer](auto &&error) {
|
}, [consumer](auto &&error) {
|
||||||
consumer.put_error_forward(std::forward<decltype(error)>(error));
|
consumer.put_error_forward(std::forward<decltype(error)>(error));
|
||||||
}, [consumer, state] {
|
}, [consumer, state] {
|
||||||
|
|
|
@ -406,6 +406,24 @@ TEST_CASE("basic operators tests", "[rpl::operators]") {
|
||||||
*sum += "done";
|
*sum += "done";
|
||||||
}, lifetime);
|
}, lifetime);
|
||||||
}
|
}
|
||||||
REQUIRE(*sum == "012done");
|
{
|
||||||
|
rpl::lifetime lifetime;
|
||||||
|
rpl::ints(3) | take(3)
|
||||||
|
| start_with_next_done([=](int value) {
|
||||||
|
*sum += std::to_string(value);
|
||||||
|
}, [=] {
|
||||||
|
*sum += "done";
|
||||||
|
}, lifetime);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
rpl::lifetime lifetime;
|
||||||
|
rpl::ints(3) | take(10)
|
||||||
|
| start_with_next_done([=](int value) {
|
||||||
|
*sum += std::to_string(value);
|
||||||
|
}, [=] {
|
||||||
|
*sum += "done";
|
||||||
|
}, lifetime);
|
||||||
|
}
|
||||||
|
REQUIRE(*sum == "012done012done012done");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -346,7 +346,7 @@ template <typename Handlers>
|
||||||
inline void producer_base<Value, Error, Generator>::start_existing(
|
inline void producer_base<Value, Error, Generator>::start_existing(
|
||||||
const consumer_type<Handlers> &consumer,
|
const consumer_type<Handlers> &consumer,
|
||||||
lifetime &alive_while) && {
|
lifetime &alive_while) && {
|
||||||
alive_while.add([consumer] { consumer.terminate(); });
|
alive_while.add(consumer.terminator());
|
||||||
consumer.add_lifetime(std::move(_generator)(consumer));
|
consumer.add_lifetime(std::move(_generator)(consumer));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,7 +38,7 @@ public:
|
||||||
limit = _count
|
limit = _count
|
||||||
](const auto &consumer) mutable {
|
](const auto &consumer) mutable {
|
||||||
auto count = consumer.template make_state<int>(limit);
|
auto count = consumer.template make_state<int>(limit);
|
||||||
return std::move(initial).start(
|
auto initial_consumer = make_consumer<Value, Error>(
|
||||||
[consumer, count](auto &&value) {
|
[consumer, count](auto &&value) {
|
||||||
auto left = (*count)--;
|
auto left = (*count)--;
|
||||||
if (left) {
|
if (left) {
|
||||||
|
@ -55,6 +55,8 @@ public:
|
||||||
}, [consumer] {
|
}, [consumer] {
|
||||||
consumer.put_done();
|
consumer.put_done();
|
||||||
});
|
});
|
||||||
|
consumer.add_lifetime(initial_consumer.terminator());
|
||||||
|
return std::move(initial).start_existing(initial_consumer);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue