Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix race condition in send/recv resulting in recv reading out of order
Currently, there is something like a `lock` on each `Node`. So, a node can be in these states: - empty (only in first lap) - available (data is available but no reader/writer) - writing (a single writer) - reading (single/multiple readers) Once the recv takes the `read` lock it can read the value safely. But doesn't mean its correct. This commit fixes the issues below, imagine: - channel size = 4, data = [0, 0, 0, 0] (0 denote empty) - send 4 elements [1, 2, 3, 4] => data = [1, 2, 3, 4]. `head` is `0`, i.e. next time we will overwrite the `1`. - `recv` starts receiving, the index is valid and is `0`. - at the same time, `send` is starting to send some data, and it will overwrite the `0`th element. At this point, several things can happen: - writer takes the lock, overwrite the data (for example with `5`) before the reader. Then the reader will read the value `5` and thinks its the current value. After that it will read `2`, `3`, `4`, which is invalid order. BAD - reader takes the lock, which is the normal correct behavior. It will read `1`, and the writer will have to wait for the reader to finish. So, we want to fix the first case. We have fixed it by adding the `lap` number to the node, so once the reader takes the lock of the node, it will check the `lap`, and this is safe since we know no writer can overwrite this `lap` value. If the value is not what we expect (the reader lap), then start the read process from the very top, which is the slowest case. But shouldn't happen very often.
- Loading branch information