-
Notifications
You must be signed in to change notification settings - Fork 360
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Support F_SETFL
and F_GETFL
#4119
Comments
Note that CLOEXEC is a file descriptor flag and not exposed via F_SETFL/F_GETFL. Those commands only handle file description flags. See the man page:
|
Looking at the kernel source code, it seems that it does not notify existing blocking operations in any way, so I would assume that they just continue to block. |
And then they get unblocked on the next read/write as usual? And at that point they might actually return EWOULDBLOCK if it turns out that not all threads could really be unblocked? I could imagine the kernel doing something smarter, but OTOH changing the blocking nature of a socket that has ongoing operations seems sufficiently odd that maybe we don't need to be bug-for-bug compatible with the kernel. |
Yeah, not sure. I guess you'll have to try it if you want to find out. |
For jobserver it would also be nice to support them on pipes. |
I'd like to push this forward, looking into this soon. @rustbot claim |
I might be wrong, but I suspect that the kernel might race in reading / modifying the In The comment here also says But in There could be other mechanisms that can prevent this from happening, but up until now, I still haven't found any. If it'd be reasonable for us to define the behaviour, I would prefer to make |
make fcntl throws EAGAIN when there is more than 1 threads blocking on it.
Does fcntl ever return that error on real systems? If not, then I don't think it would be a good idea to do that in Miri.
|
Yes, these are documented in https://man7.org/linux/man-pages/man2/fcntl.2.html#ERRORS
The reason why I chose
the above is from taken from https://man7.org/linux/man-pages/man3/errno.3.html |
But does it happen in practice? Tokio certainly does not handle it. |
I tried to write a test that triggers |
What is the codepath you are attempting to hit? I don't see a codepath in the kernel that returns |
I was trying to reason what would happen when we have this interleaving:
I am not too sure which codepath in the kernel would this behaviour hit. my another question is would it be possible to have read of flag in pipe_read and this modify of flag in setfl happen without synchronisation? |
Most likely the pipe read continues blocking like normal until something wakes it up, at which point it either returns like normal, or notices that the flag has been set and then it returns wouldblock. I don't think changing the flag causes existing read calls to immediately return wouldblock. And yes they probably read the flag without synchronization that case. They probably should take the lock, but yolo 🤷 You can assume it behaves like they locked and immediately unlocked it, i.e. it gets whatever the value is at that time, because that's probably indeed what does happen in practice. |
trying to reason what would happen when we have this interleaving
You should be able to test this by having two threads, and having one thread sleep for a second before calling fcntl - by then the other thread almost surely has hit the blocking read.
|
Oh yes, I managed to call
|
Okay, so basically on a write should just always unblock waiting writers -- even if the pipe is currently non-block. |
I tested a new case, if we call
So my current mental model if very close to what @Darksonn stated above, if This shouldn't be hard to replicate in miri. If this model is ok, I'll start working on an implementation. |
This is proposed to support some tests in tokio.
Ideally we could support
F_SETFL
andF_GETFL
for all kind of file descriptions, but getting them to work onsocketpair
should be sufficient to unblock some of the tests there (here is the relevant codepath).F_GETFL
is quite straight forward as we only supportSOCK_NONBLOCK
andSOCK_CLOEXEC
flags forsocketpair
.For
F_SETFL
, as it has the ability to changeO_NONBLOCK
flag, we need to decide what should happen if a previously blocking fd is marked as non-blocking, and there are waiting threads. Should they wake up immediately, later at some point or never? It might make this previously unreachable case, reachable.Ideally support this on:
@rustbot label +A-shims +C-enhancement +A-concurrency
The text was updated successfully, but these errors were encountered: