Skip to content

Commit e082ee0

Browse files
authored
fix handle spurious wakeup wrongly returning Flush too early (#340)
add an atomic bool to check if flush has actually happened and condition variable did not spuriously wakeup. fixes #339
1 parent cf7de04 commit e082ee0

2 files changed

Lines changed: 18 additions & 13 deletions

File tree

keyvi/include/keyvi/index/internal/index_writer_worker.h

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -211,17 +211,20 @@ class IndexWriterWorker final {
211211
} else {
212212
std::condition_variable c;
213213
std::unique_lock<std::mutex> lock(payload_.flush_mutex_);
214+
std::atomic_bool flushed{false};
214215

215-
compiler_active_object_([&c](IndexPayload& payload) {
216-
{
217-
PersistDeletes(&payload);
218-
Compile(&payload);
219-
std::unique_lock<std::mutex> lock(payload.flush_mutex_);
220-
}
216+
compiler_active_object_([&c, &flushed](IndexPayload& payload) {
217+
std::unique_lock<std::mutex> lock(payload.flush_mutex_);
218+
PersistDeletes(&payload);
219+
Compile(&payload);
220+
flushed = true;
221221
c.notify_all();
222222
});
223223

224-
c.wait(lock);
224+
// condition may be unblocked spuriously, check flushed
225+
while (flushed == false) {
226+
c.wait(lock);
227+
}
225228
}
226229
}
227230

keyvi/tests/keyvi/index/index_limits_test.cpp

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@
3737
#include "keyvi/index/index.h"
3838

3939
inline std::string get_keyvimerger_bin() {
40-
boost::filesystem::path path{std::getenv("KEYVI_UNITTEST_BASEPATH")};
40+
boost::filesystem::path path{std::getenv("KEYVI_UNITTEST_BASEPATH")}; // NOLINT
4141
path /= DEFAULT_KEYVIMERGER_BIN;
4242

4343
BOOST_CHECK(boost::filesystem::is_regular_file(path));
@@ -46,10 +46,12 @@ inline std::string get_keyvimerger_bin() {
4646
}
4747

4848
inline size_t limit_filedescriptors(size_t file_descriptor_limit) {
49-
struct rlimit limit;
49+
struct rlimit limit {
50+
0
51+
};
5052

5153
getrlimit(RLIMIT_NOFILE, &limit);
52-
size_t old_limit = limit.rlim_cur;
54+
const size_t old_limit = limit.rlim_cur;
5355
limit.rlim_cur = file_descriptor_limit;
5456
BOOST_CHECK(setrlimit(RLIMIT_NOFILE, &limit) == 0);
5557
getrlimit(RLIMIT_NOFILE, &limit);
@@ -65,7 +67,7 @@ BOOST_AUTO_TEST_CASE(filedescriptor_limit) {
6567
using boost::filesystem::temp_directory_path;
6668
using boost::filesystem::unique_path;
6769

68-
size_t old_limit = limit_filedescriptors(40);
70+
const size_t old_limit = limit_filedescriptors(40);
6971

7072
auto tmp_path = temp_directory_path();
7173
tmp_path /= unique_path("index-limits-test-temp-index-%%%%-%%%%-%%%%-%%%%");
@@ -80,13 +82,13 @@ BOOST_AUTO_TEST_CASE(filedescriptor_limit) {
8082
}
8183
writer.Flush();
8284
BOOST_CHECK(writer.Contains("a"));
83-
dictionary::match_t m = writer["a"];
85+
const dictionary::match_t m = writer["a"];
8486

8587
BOOST_CHECK_EQUAL("{\"id\":4999}", m->GetValueAsString());
8688
}
8789
boost::filesystem::remove_all(tmp_path);
8890

89-
size_t increased_file_descriptors = keyvi::util::OsUtils::TryIncreaseFileDescriptors();
91+
const size_t increased_file_descriptors = keyvi::util::OsUtils::TryIncreaseFileDescriptors();
9092
BOOST_CHECK(increased_file_descriptors > 40);
9193

9294
limit_filedescriptors(old_limit);

0 commit comments

Comments
 (0)