> UNIX system calls never do this. The kernel won't keep references to pointers you pass them and write to them later. It just isn't in the DNA. The only exceptions I can think of would be clone(), which is abstracted by the POSIX threads runtime, and Windows-inspired non-standard system calls like epoll.
I mean, this is because the UNIX model was based on readiness rather than completion. Which is slower. Hence the newer I/O models.
There are evented I/O APIs for Unix, though anything other than select(2) and poll(2) is non-standard, and while some do let you use pointer-sized user cookies to identify the events I've never seen a case where a programmer used a stack address as a cookie. I have seen cases where the address used as the cookie was freed before the event registration was deleted, or before it fired, leading to use-after-free bugs.
No, IOCP is not a workaround for syscall overhead. In fact this performance hit has nothing to do with syscall overhead. The overhead is O(1). The penalty of the readiness design is O(n). Because if the system can't copy into your n-byte buffer in the background, then you gotta block for O(n) time to memcpy it yourself.
That said, it would be insane to pass it pointers to the stack, as the only safe way to make that work would be to do `aio_suspend()` or busy wait and you might as well just use a synchronous read() function in that case.
> as the only safe way to make that work would be to do `aio_suspend()` or busy wait and you might as well just use a synchronous read() function in that case.
Wait but read() wouldn't allow overlapping operations. Whereas if you suspend or busy wait you can do that for multiple operations executing concurrently.
Also if the buffer is from a caller frame then you could also return safely no?
I mean, this is because the UNIX model was based on readiness rather than completion. Which is slower. Hence the newer I/O models.