Split lazy server and lazy client types. They're very different and do very different things.
Combine lazy client write with handshake. This allows us to negotiate and write all in one go.
I'm not happy with the server-side logic but couldn't find a nice, clean way to fix it so I left it as it was (mostly). Eventually, we'll have to switch to a new protocol anyways because this one isn't sound.
Note: there's one TODO. The test cases assume that reads with zero-length buffers will succeed instantly. This can hide errors and is wrong. Should I just fix the tests?
Coverage decreased (-2.2%) to 77.262% when pulling ae3268d28241403197ee0dad40d2bd39f1163da9 on fix/race into b8f1996688ab586031517919b49b1967fca8d5d9 on master.
Coverage decreased (-1.9%) to 77.506% when pulling ae3268d28241403197ee0dad40d2bd39f1163da9 on fix/race into b8f1996688ab586031517919b49b1967fca8d5d9 on master.
I'm not happy with the server-side logic but couldn't find a nice, clean way to fix it so I left it as it was (mostly). Eventually, we'll have to switch to a new protocol anyways because this one isn't sound.