mirror of
https://github.com/justinian/jsix.git
synced 2025-12-10 08:24:32 -08:00
[util] Fix bip_buffer concurrency bug
If a bip_buffer's A buffer is in the middle of being appended to, but that append has not yet been committed, and all committed A data has been read, the buffer would get into a bad state where m_start_r pointed to the end of the previous A buffer, but that data is no longer connected to either A or B. So now we make sure to check m_size_r before considering A "done".
This commit is contained in:
@@ -71,7 +71,7 @@ void bip_buffer::commit(size_t size)
|
||||
scoped_lock lock {m_lock};
|
||||
|
||||
assert(size <= m_size_r && "Tried to commit more than reserved");
|
||||
|
||||
if (m_size_r) {
|
||||
if (m_start_r == m_start_a + m_size_a) {
|
||||
// We were adding to A
|
||||
m_size_a += size;
|
||||
@@ -80,7 +80,7 @@ void bip_buffer::commit(size_t size)
|
||||
assert(m_start_r == m_start_b + m_size_b && "Bad m_start_r!");
|
||||
m_size_b += size;
|
||||
}
|
||||
|
||||
}
|
||||
m_start_r = m_size_r = 0;
|
||||
}
|
||||
|
||||
@@ -98,9 +98,16 @@ void bip_buffer::consume(size_t size)
|
||||
|
||||
assert(size <= m_size_a && "Consumed more bytes than exist in A");
|
||||
if (size >= m_size_a) {
|
||||
if (m_size_r && m_start_r == m_start_a + m_size_a) {
|
||||
// A is still being appended to
|
||||
m_start_a = m_start_r;
|
||||
m_size_a = 0;
|
||||
} else {
|
||||
// A is done, B becomes A
|
||||
m_size_a = m_size_b;
|
||||
m_start_a = m_start_b;
|
||||
m_size_b = m_start_b = 0;
|
||||
}
|
||||
} else {
|
||||
m_size_a -= size;
|
||||
m_start_a += size;
|
||||
|
||||
Reference in New Issue
Block a user