Path: utzoo!utgpu!news-server.csri.toronto.edu!rutgers!cbmvax!uunet!world!bzs From: bzs@world.std.com (Barry Shein) Newsgroups: comp.unix.misc Subject: Re: UNIX semantics do permit full support for asynchronous I/O Message-ID: Date: 8 Sep 90 02:41:03 GMT References: <1990Aug29.170931.10853@terminator.cc.umich.edu> <31445.26dc0466@ccavax.camb.com> <1990Aug31.142906.26633@uncecs.edu> <1990Sep04.014353.15085@gorgon.uucp> <1990Sep5.142127.13771@sco.COM> Sender: bzs@world.std.com (Barry Shein) Distribution: usa Organization: The World Lines: 80 In-Reply-To: seanf@sco.COM's message of 5 Sep 90 18:21:27 GMT From: seanf@sco.COM (Sean Fagan) >>As an extension to Unix, I would suggest the following: > >I wouldn't (reasons below), but a small comment on your method anyway: > >> int writea(int fileno, void *buffer, size_t buflen, void (*complete_rtn)()); >> int reada(int fileno, void *buffer, size_t buflen, void (*complete_rtn)()); > >Change that the 'complete_rtn' to: > > void (*complete_rtn)(int) > >where the parameter is the return value of the call, either the number of >bytes read/written, or the failure/return code. Perhaps - on >failure? Well, I wouldn't do it either, at least not until some evidence is presented indicating it's worthwhile (to someone other than a salesperson trying to sell Unix to a VMS customer...) BUT...I'd change this further: int write/reada(....,void (*complete_rtn),caddr_t arg); void (*complete_rtn)(caddr_t,int,int); where: caddr_t a user supplied argument int the file descriptor int the result as described This would allow multiplexing of several async I/O's thru one routine, or even posting more than one on the same fd and knowing which finished without having to maintain an external state (or in the case where it might be possible they finish in a different order than requested, which might be possible due to disk queue re-ordering or similar considerations.) Something you might also want in that result, or yet another arg, would be whether it was a read or a write or whatever it was that completed, tho I guess one could argue that this should be mux'd via different completion routines. But I bet that would lead to this sort of silliness: #define IO_READ 1 #define IO_WRITE 2 void awrite_complete(fnp,fd,result)... { (*fnp)(IO_WRITE,fd,result); } aread_complete(fnp,fd,result)... { (*fnp)(IO_READ,fd,result); } where both fnp's are the same, ah well (this would be because a lot of common code is used on read or write, like just setting a bit in a commit map.) Providing the fd would, for example, allow the completion routine to close the file on EOF (or even take some action, like rewind/offload a tape etc, on ERROR, without all sorts of global state.) Note that errno on entry to the completion routine had better be the errno resulting from the I/O or I'd be quite upset. Gee, maybe the buffer should be passed also...I guess you could argue that could go into the caddr_t which could point to a structure, I'd buy that I guess. Then again I haven't read the POSIX spec, how close does it come to all this? -- -Barry Shein Software Tool & Die | {xylogics,uunet}!world!bzs | bzs@world.std.com Purveyors to the Trade | Voice: 617-739-0202 | Login: 617-739-WRLD