update readme
[c11concurrency-benchmarks.git] / bugreports / mabain.1.mb_multi_thread_insert_test
1 diff --git a/mabain/src/async_writer.cpp b/mabain/src/async_writer.cpp
2 index 1f35d54..0c3183a 100644
3 --- a/mabain/src/async_writer.cpp
4 +++ b/mabain/src/async_writer.cpp
5 @@ -135,6 +135,21 @@ int AsyncWriter::StopAsyncThread()
6      }
7  #endif
8  
9 +    while (true) {
10 +        bool finished = true;
11 +        for(int i = 0; i < header->async_queue_size; i++)
12 +        {
13 +            AsyncNode *node_ptr = &queue[i % header->async_queue_size];
14 +            if (node_ptr->type == MABAIN_ASYNC_TYPE_ADD)
15 +                finished = false;
16 +        }
17 +
18 +        if (finished)
19 +            break;
20 +        else
21 +            nanosleep((const struct timespec[]){{0, 10L}}, NULL);
22 +    }
23 +
24      stop_processing = true;
25
26
27 == Description ==
28 When the main thread opens an instance of the mabain database with the ASYNC_WRITER_MODE, it launches a second thread executing "AsyncWriter::async_writer_thread".  This function is an infinite while loop in which thread 2 keeps popping nodes from a so called "shm_queue" and inserting nodes into the database.
29
30 Then the main thread launches four threads (thread 3, 4, 5, and 6) to "insert" keys into the database.  These four threads actually only push keys into the shm_queue, instead of inserting directly into the database. 
31
32 The main thread is blocked until thread 3, 4, 5, and 6 join.  Right after they join, (i.e. all keys have been pushed into the shm_queue), the main thread closes the database and tells thread 2 to stop processing.  The problem is when thread 2 stops, some keys may still be left in the shm_queue, and have not been inserted into the database. 
33
34 The newer version of mabain (last updated on July 31, 2019, with commit hash 0c40e9393d4e3b337d6e20f458ff6d5ee67c174c) also has this bug. 
35
36 For the newer version, when threads 3, 4, 5, and 6 try to insert a key into the database, they did attempt to insert this key directly into the database in the first place (with the protection of a std::timed_mutex).  If this attempt fails (for example when timed_mutex::try_lock_for times out), then they will push the key into the shm_queue, which may trigger the old bug.