From 9a681d6669d5d1c6f5b681af78b8d15e6075917b Mon Sep 17 00:00:00 2001 From: zeyus Date: Thu, 10 Apr 2025 16:52:31 +0200 Subject: [PATCH 1/4] Possibly fix #218 - next->_next might be unavailble. --- src/sample.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/sample.cpp b/src/sample.cpp index b95521b0..9a64c756 100644 --- a/src/sample.cpp +++ b/src/sample.cpp @@ -466,11 +466,13 @@ sample *factory::pop_freelist() { } factory::~factory() { - for (sample *cur = tail_, *next = cur->next_;; cur = next, next = next->next_) { - if (cur != sentinel()) delete cur; - if (!next) break; - } - delete[] storage_; + sample *cur = tail_; + while (cur) { + sample *next = cur->next_; // Save next pointer before potentially deleting cur + if (cur != sentinel()) delete cur; + cur = next; + } + delete[] storage_; } void factory::reclaim_sample(sample *s) { From afacf89a71262f44d5e4fdb9f70dc5490b60ddd5 Mon Sep 17 00:00:00 2001 From: zeyus Date: Thu, 10 Apr 2025 17:04:22 +0200 Subject: [PATCH 2/4] Try deleting later. --- src/sample.cpp | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/src/sample.cpp b/src/sample.cpp index 9a64c756..a05b85d0 100644 --- a/src/sample.cpp +++ b/src/sample.cpp @@ -466,13 +466,25 @@ sample *factory::pop_freelist() { } factory::~factory() { - sample *cur = tail_; - while (cur) { - sample *next = cur->next_; // Save next pointer before potentially deleting cur - if (cur != sentinel()) delete cur; - cur = next; - } - delete[] storage_; + // get pending samples + std::vector pending; + sample *cur = tail_.load(); + + // add them without deleting + while (cur) { + if (cur != sentinel()) { + pending.push_back(cur); + } + sample *next = cur->next_.load(); + cur = next; + } + + // now delete the samples + for (sample* s : pending) { + delete s; + } + + delete[] storage_; } void factory::reclaim_sample(sample *s) { From 1c7ccec40d7c51d87fd3dacafa9f52cfe5f6987b Mon Sep 17 00:00:00 2001 From: zeyus Date: Thu, 10 Apr 2025 17:20:23 +0200 Subject: [PATCH 3/4] Try only deleting samples outside storage. --- src/sample.cpp | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/src/sample.cpp b/src/sample.cpp index a05b85d0..9fa41c55 100644 --- a/src/sample.cpp +++ b/src/sample.cpp @@ -466,24 +466,17 @@ sample *factory::pop_freelist() { } factory::~factory() { - // get pending samples - std::vector pending; sample *cur = tail_.load(); - - // add them without deleting while (cur) { - if (cur != sentinel()) { - pending.push_back(cur); - } sample *next = cur->next_.load(); - cur = next; - } - // now delete the samples - for (sample* s : pending) { - delete s; - } + // Only delete samples that are outside of storage area + if (cur != sentinel() && (static_cast(cur) < storage_ || + static_cast(cur) >= storage_ + storage_size_)) + delete cur; + cur = next; + } delete[] storage_; } From e37971c4b8e0985f31bf58f306d89c00137db9ce Mon Sep 17 00:00:00 2001 From: zeyus Date: Fri, 11 Apr 2025 15:38:38 +0200 Subject: [PATCH 4/4] Just testing... --- testing/ext/bench_pushpull.cpp | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/testing/ext/bench_pushpull.cpp b/testing/ext/bench_pushpull.cpp index a5b7e020..fc7e8ee9 100644 --- a/testing/ext/bench_pushpull.cpp +++ b/testing/ext/bench_pushpull.cpp @@ -32,10 +32,11 @@ TEMPLATE_TEST_CASE("pushpull", "[basic][throughput]", char, double, std::string) auto found_stream_info(lsl::resolve_stream("name", name, 1, 2.0)); REQUIRE(!found_stream_info.empty()); - std::list inlet_list; for (auto n_inlets : param_inlets) { + std::list inlet_list; while (inlet_list.size() < n_inlets) { - inlet_list.emplace_front(found_stream_info[0], 300, false); + lsl::stream_info info_copy(found_stream_info[0]); + inlet_list.emplace_front(info_copy, 300, false); inlet_list.front().open_stream(.5); } std::string suffix(std::to_string(nchan) + "_inlets_" + std::to_string(n_inlets)); @@ -49,7 +50,20 @@ TEMPLATE_TEST_CASE("pushpull", "[basic][throughput]", char, double, std::string) out.push_chunk_multiplexed(data, chunk_size); for (auto &inlet : inlet_list) inlet.flush(); }; + + // Explicitly close and delete the inlets to ensure that they are not + // still in use when the next inlet is created. + for (int i = 0; i < n_inlets; i++) { + inlet_list.back().close_stream(); + inlet_list.pop_back(); + } + } + // Wait until all inlets are closed + // this hangs forever + // while (out.have_consumers()) { + // std::this_thread::sleep_for(std::chrono::milliseconds(1)); + // } } }