From: Franck A. <fr...@ne...> - 2003-06-24 23:51:03
|
Berend de Boer: > blocking or non-blocking is just an option you can enable/disable at > any given time. It's not an is-a relation. In POSIX, but this does not mean all Eiffel abstractions of IO must blindly follow. Example of possible Eiffel designs include separate classes and no switchability, or a switchable class as well as a purely blocking class in the same library. > But your proposal has not much to do with DbC IMO. The contract is > simply wrong. It's not really 'wrong' in that you want to use a class for something else than it is designed to do. It may be possible to make the abstraction cope with this, but this is about changing the abstraction, not making right something wrong. > It seems that a read that returns 0 bytes is simply valid, even for > non-blocking descriptors In this spec. KI*STREAM is not a direct abstraction for this, and if there is a discrepancy between the Gobo abstraction and an OS API, the implementation can adapt accordingly (unless impractical). > > if has_thing then > > do_something_with (get_thing_surely) > > else > > do_when_no_thing > > end > > If you change the class with a precondition you put a burden on every > programmer for every program even when non-blocking isn't an issue. When blocking, we have an invariant has_thing = True hence no burden. Similarly a /= Void precondition does not require all clients to check explicitely when they know what they pass is /= Void. > >> 2. Not all unixes might have poll/select support. > > > > Example? There may be some patchy standardisation, > poll/select is *not* in POSIX 1996. I agree the standard situation may be a problem, I was just saying that not standardised /= not available. > Blocking i/o is [in POSIX 96]. Of course, but is non-blocking? I guess you meant it is. > My class is all about given exactly POSIX semantics and > options to the programmer. You can do that with a precondition API, you just need some adaptation between the abstraction and the posix calls. > If the world was that simple. I'm afraid no POSIX specs defines > exactly what you think it does We're discussing about the Eiffel abstraction! It's your job to have glue code that maps the Eiffel abstraction to the POSIX or whatever API. The abstraction should be good enough so that the mapping is practical, but there's no necessity to map 1:1 Gobo features to system calls. > The definition of select() is: true implies read() does not block. It > does not say read() does return > 0 bytes. select() would be useless if it usually returned when there is 0 bytes. You can surely deal with the freak cases in the mapping. > >> 5. It seems pretty pointless to have non-blocking i/o when you first > >> have to test for availability for data. At best you have to read > >> from the input twice, with double the overhead. > > > > You don't read twice, you wait for readability, and then read. It's > > That's two kernel calls. Twice the overhead. If you implement it that way. You can also implement has_something_to_read with a call that actually reads and keeps the result for the next read_to_string call. > My main point is that *having* to check if data is available is > inherently slower. Is it? There's no check if blocking, mapping can issue the same sequence of sys call for both Eiffel abstractions so no unavoidable OS call overhead, and it is a small subset of non blocking use cases where you don't have to select() anyway. > My argument for removing the contract was to avoid introducing a > non-blocking status to a base class that is of no use to Gobo as it is > now. But I certainly am happy with such a status if people agree. I'd rather see explicit semantics even if it makes a more complicated class than extra behaviour hidden behing borderline unspecified cases. -- fr...@ne... |