-
Notifications
You must be signed in to change notification settings - Fork 32
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
io-wakeup: Use file descriptors when calling select. #96
base: master
Are you sure you want to change the base?
Conversation
ab1f9de
to
f915c14
Compare
No. This is incompatible with ‘move->fdes’ and friends, as it is possible for a different thread to adjust the file descriptor of the port between 'port-read-wait-fd' and ‘select'. (Yes, Fibers already has this bug in fibers/epoll.scm, but that doesn't mean we should increase the number of instances of this bug.) It also a problematic in a different way: it assumes the port has a file descriptor that can meaningfully be directly selected. While writing Scheme-GNUnet, I am intending to allow accessing CADET ‘channels’ (or whatever the terminology was ...) as ports, and they aren't even implemented as something on top of file descriptors.
Instead, why not make ‘select’ work on these ports? Also, I'm wondering which ports these are. Alternatively, if the ‘select accepts a list/vector of ports’ is difficult to implement, it would be sufficient to have something like ‘readable?’ / ‘writable?’ directly in Guile. |
(They aren't implemented at all yet, but that's a separate issue.) |
f915c14
to
9a0369a
Compare
Ok.
That seems like a design/implementation limitation to me, not a bug.
I think assuming that the port has a file descriptor is fine, fibers makes that assumption elsewhere: https://github.com/wingo/fibers/blob/master/fibers.scm#L56-L63
Right, so what's the problem? If that port isn't directly blocking reading or writing on a file descriptor, then it's not relevant to fibers as it's not going to block at a low level?
|
Adding this new design/implementation limitation to io-wakeup is a bug, because nowhere does the documentation of io-wakeup state that that you must not move the fdes of the port. I'm not opposed to adding such a limitation (AFAIK
This reasoning makes no sense. Just because Fibers makes an assumption somewhere doesn't mean that this assumption should be made elsewhere as well -- for ‘wait-for-readable’, there currently is no other option but to use the file descriptor and assume it has a file descriptor, whereas for ‘wait-until-port-readable-operation’, it doesn't need to make such an assumption.
The problem is ... what I wrote above. Whether the blocking happens at an fd level or not and at a low level or high level is ... utterly irrelevant (*)? What matters is whether it will block, not on which layer it will block -- it is, after all, wait-until-port-readable, not wait-until-fd-readable. For a concrete example, look at https://git.gnunet.org/gnunet-scheme.git/tree/gnu/gnunet/mq-impl/stream.scm. Except for setting the While that example uses fd-backed ports, I don't think it's hard to imagine that in the future, someone may want to wait on the readability of non-fd ports -- for example, to wait on the readability of a CADET thing. And it would be great if non-fd ports and fd ports had the same interface for this, to enable writing code that's agnostic on what kind of port it is passed. More concretely, I intend to do that eventually in the tests of Scheme-GNUnet, to make tests have less side-effects by not creating UNIX file-system-backed sockets and not having to clean them up afterwards. (*) except for the implementation of the operation. As it turns out that ‘select’ requires file descriptors and I don't see a good way of generalising this, I now intend to write a (separate) patch to address this.
This doesn't answer the question, unless this is an indirect way of stating that ‘these ports’ don't have file descriptors. But that's contradicted by the fact that your are using ‘port-read-wait-fd’ and hence the ports do, in fact have file descriptors. If I understood correctly, it looks like you should modify 'select' to do that (in Guile), and as a temporary workaround (in Fibers) only use 'port-x-wait-fd' if the ‘(fileno port)’ returns `#false'. |
* fibers/io-wakeup.scm (wait-until-port-writable): Replace readable? by writable?. Reported-by: cbaines See: #96 (review)
Looks like io-wakeup already assumes ports have fdes (see e.g. make-read-operation/make-write-operation), which mostly does away with the concerns about new uses port-read-wait-fd and friends. Still, [...]
[...] seems to apply. |
(*) except for the implementation of the operation. As it turns out that ‘select’ requires file descriptors and I don't see a good way of generalising this, I now intend to write a (separate) patch to address this. See (untested) branch |
I just don't see how or why you want to wait for reading or writing to a port that's not blocking on a file descriptor? If you implement a port in Guile that does something that's going to block, say calling some native code, then you do something there to make that cooperate with fibers. That makes perfect sense to me. But there's no general way in Guile of magically waiting until any kind of port can be read from or written to without blocking, because it's very specific to the implementation of that port. And as above, I don't believe you need to do this, you can still write all kinds of ports that interact well with fibers.
As above, I don't think this makes sense, because there's no mechanism to make it work. If there was some way in Guile for you to hook in to ports to know how to wait on them being readable or writable, then this would be a possibility, but there isn't, the mechanism available is that ports can share the relevant file descriptors, then you do something with them. And again, this shouldn't cause you problems if you're using a port that isn't backed by a file descriptor, but does something that blocks, as you need to cooperate with fibers internally within the implementation of the port.
I don't really follow the example you give, but again, unless I've missed something massively in Guile, there is no mechanism to wait on the readability or writability of ports in general. And I don't think there needs to be. Trying to design code in fibers around that (which I don't think exists) doesn't seem sensible. |
How: with wait-until-... and the new branch fdless-draft. So, I could just not wait for blocking, but the thing is that I want to wait for blocking or for another operation (e.g. a condition or channel indicating the fiber can stop, as in the example). Without an operation to wait for blocking, the fiber would could keep going even after it should be stopped.
See the new branch, which has the basics of making this work.
Again, see the new branch.
Again, see the new branch, which provides a mechanism for the implementation of the port to cooperate with fibers.
There does need to be a mechanism: see the example.
It makes sense to do that in Fibers instead of Guile, because operations are a Fibers construct, not a Guile construct. |
Also, if it's not considered a sensible thing, then I would say that this non-sensible thing is really useful, neat, straightforward to implement (it even has an implementation already: see the patch), desired (*) and doesn't interfere with anything else, and as such the nonsensibility is not a concern. (*) source for the last part: me. |
In my experience, I actually need it for Scheme-GNUnet, for both current code, future code and likely future users of Scheme-GNUnet. If you want to demonstrate the contrary, go ahead and rewrite current code, write future code and write an application using Scheme-GNUnet for GNUnet stuff, I wouldn't mind some extra contributors, but insisting that this is false with only words isn't getting you anywhere. |
Look let's stop making things harder for my pet project (Scheme-GNUnet) and focus on making wait-until-whatever slightly more general to cover your ports, of which you still haven't answered why you don't just implement select for those ports. Again, it would help if you actually said what those currently-unsupported ports are. |
No. If Look if you will continue this as you did previously, you're failing reading comprehension and I'll be closing this PR. |
9a0369a
to
b9c73d8
Compare
Select only works for file ports or file descriptors, so pass in the appropriate file descriptor when not using a file port. * fibers/io-wakeup.scm (readable?, writable?): Take a port or fd. (try-ready): Take port-ready-fd, and use this when calling ready? if port is not a file port. (wait-until-port-readable-operation): Pass port-read-wait-fd to try-ready. (wait-until-port-writable-operation): Pass port-write-wait-fd to try-ready.
b9c73d8
to
4bd3621
Compare
Right, there's some missing information. You don't just want to interact with ports not backed by file descriptors, but you want to construct fibers operations that involve whether some port in general (including those not involving file descriptors) is readable/writable. I guess that should be technically possible, but I don't know how it would be done. Maybe it can be done in the future by
The ports you get back from
Recent versions of guile-gnutls do set the read and write file descriptors on the port, which enables them to be used with suspendable ports/fibers.
Up until now we've been talking about different things. I did have a go at reading the code sample you gave, but I found it difficult to follow and I didn't manage to figure out that you were trying to use the fibers operations around ports in conjunction with other operations. Now you've said you want to do that, I can understand why you want this code to work more generally. As for your suggestion to make Ignoring the part of this discussion about the hypothetical use of this code on ports not involving file descriptors, you have given useful feedback which I've incorporated. |
Someone else can handle this PR, I can't anmore. @aconchillo, @wingo? p.s. Is there a list of maintainers somewhere? |
Rather than ports, since select doesn't work for all ports in Guile.