5 ms·
> the readv() call will block until all iovec buffers are fil led with file data. Once it returns, we should be able to access the file data from the iovecs an
by Matthias247 7y ago
> the readv() call will block until all iovec buffers are fil led with file data. Once it returns, we should be able to access the file data from the iovecs and print them on the console.
This is wrong. readv() can return as soon as a single byte had been read, in a similar fashion as read(). If you need to read all bytes you have to use a loop. This program is potentially printing non-initialized memory.
I think the same applies to the uring examples, which also don't seem to check the actual processed bytes.
I'm also actually not sure if in the uring version requests are guaranteed to be processed in order or not. I would have assumed the latter - and thereby the printed result could have been out of order.
Obviously the demos also miss all the required memory management - but I guess that was intended. But if we would add it, the uring versions would increase more in complexity than the synchronous version.
==> IO is hard. uring is exciting for high performance use-cases, but will rather make it harder than easier. However ideally most end-users would not have to use it directly (and neither liburing), but instead use an async/await/coroutine framework on top of it that makes the asyncness transparent to the application and allows to avoid most of the pitfalls.
- yxhuvud 7y ago> I'm also actually not sure if in the uring version requests are guaranteed to be processed in order or not. I would have assumed the latter - and thereby the printed result could have been out of order. You assume correctly. There is no ordering guarantee, unless events are chained (which is a special flag).
- shuss 7y agoFirst off, you're right that readv(), like read() can indeed return lesser data than was requested. Thanks. I'll fix that. > I'm also actually not sure if in the uring version requests are guaranteed to be processed in order or not. I would have assumed the latter - and thereby the printed result could have been out of order. io_uring may not make completions available in the same order as submissions. The article goes into some detail explaining this. However, the "cat" example only deals with one request at a time which uses readv() and readv()'s iovecs are returned in order. So, this is not a problem. The "cp" example does deal with multiple submissions and completions, however it uses writev() on the completion of each readv(), writing the correct offsets. So, it wouldn't matter if completions arrive out of order. But this is indeed something to look out for.
- tene 7y agohttps://docs.rs/rio/ https://docs.rs/rio/ is a pretty credible attempt at providing a misuse-resistant API for io_uring, both synchronous and async. There's still some nonzero complexity in using it instead of read/write, but it doesn't seem particularly burdensome to me. I've got a lot of hope for higher-level misuse-resistant libraries on top of io_uring.
- jstarks 7y agoUnfortunately rio is unsound (and the maintainer doesn’t seem to care) [1]. It’s also GPL3 which limits its use in many projects. But I too am hopeful. Just not for rio’s API model specifically. [1] https://github.com/spacejam/rio/issues/11 https://github.com/spacejam/rio/issues/11
- staticassertion 7y agoThis doesn't read to me as "the maintainer doesn't seem to care" so much as they feel that the unsafety is likely an edge case and, in another issue, there's some more discussion around fixing it. https://github.com/spacejam/rio/issues/12#issuecomment-583759740 https://github.com/spacejam/rio/issues/12#issuecomment-58375...
- codys 7y ago`forgetting` is not an edge case. In the context of rust, having an API that invokes unsafe behavior without it being marked unsafe is not acceptable. Keeping ourselves to this rule is what makes the concept of `unsafe` useful because we can rely on the behavior/api-spec of other code. Failing to ensure correct behavior in the presence of `forget` means that once the program gets complex enough it can blow up in undetermined ways because one piece of code somewhere wasn't aware of a restriction in another piece of code that is potentially very far away. Failing to isolate this type of unsafety is a pitfall waiting for some future developer to be trapped in.
- staticassertion 7y ago
- carterli 7y agoHere is an async/await/coroutine (lib)uring binding written in C++, plus performance suggestions, benchmarks and demo usage. Be sure to check it https://github.com/CarterLi/liburing4cpp https://github.com/CarterLi/liburing4cpp