Don't lose data when doing non-blocking I/O

Closed Stefano Rivera requested to merge bitbucket/declined-pr-12 into branch/default

Changesets for this Pull Request have not been imported, because it had been already declined on Bitbucket. Marked as closed by the import user.

Continuing on from 3f96afe7cdc2, I looked for all other possible data loss, when EAGAIN's could be thrown.

The common scenario is that many layers of the stream stack temporarily cache read data, while read()ing in a loop, and then return the data, concatenated. This breaks when you receive an EAGAIN.

I started by auditing the code to find possible problems, then writing tests that could expose them, then fixing the bugs. There isn't a strict relationship between tests and patches, rather, vaguley-comprehensive tests.

The tests are a bit ugly, I can't see any way to avoid massive code duplication or multiple asserts per test. Suggestions welcome :)

Merge request reports