Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 20 Oct 2004 14:11:36 -0700
From:      "Ronald F. Guilmette" <rfg@monkeys.com>
To:        Igor Sysoev <is@rambler-co.ru>
Cc:        freebsd-net@freebsd.org
Subject:   Re: aio_connect ? 
Message-ID:  <79296.1098306696@monkeys.com>
In-Reply-To: Your message of Wed, 20 Oct 2004 23:51:36 %2B0400. <20041020233952.V17688@is.park.rambler.ru> 

next in thread | previous in thread | raw e-mail | index | archive | help

In message <20041020233952.V17688@is.park.rambler.ru>, you wrote:

>> There are clearly cases in which one would like to perform reads
>> asynchronously, but likewise, there are cases where one might like
>> to also perform socket connects asynchronously.  So how come no
>> aio_connect?
>
>In FreeBSD you can do connect() on the non-blocking socket, then set
>the socket to a blocking mode, and post aio_read() or aio_write()
>operations on the socket.

As I earlier noted, in this thread, that approach _does not_ provide
quite the same semantics as aio_*() with signaling upon completion.

>While the developing my server nginx, I found the POSIX aio_* operations
>uncomfortable. I do not mean a different programming style, I mean
>the aio_read() and aio_write() drawbacks - they have no scatter-gather
>capabilities (aio_readv/aio_writev)

You could add those.  They would just be your personal extensions... at least
until you propose them and get them accepted by the POSIX people for the
next revision of the standard.

> and they require too many syscalls.
>E.g, the reading requires
>*) 3 syscalls for ready data: aio_read(), aio_error(), aio_return()
>*) 5 syscalls for non-ready data: aio_read(), aio_error(),
>   waiting for notification, then aio_error(), aio_return(),
>   or if timeout occuired - aio_cancel(), aio_error().

This assumes that one is _not_ using the signaling capabilities of the
aio_*() functions in order to allow the kernel to dynamically signal the
userland program upon completion of a previously scheduled async I/O
operation.  If however a programmer were to use _that_ approache to de-
tecting I/O completions, then the number of syscals would be reduced
accordingly.

However this all misses the point.  As I noted earlier in this thread, 
efficience _for the machines_ is not always one's highest engineering
design goal.  If I have a choice between building a more maintainable,
more adaptable, more modularized program, or instead building a more
machine-efficient program, I personally will almost always choose to
build the clearly, more modularized program as opposed to trying to
squeeze every last machine cycle out of the thing.  In fact, that is
why I program almost exclusively in higher level languages, even though
I could almost certainly write assembly code that would almost always be
faster.  Machine time is worth something, but my time is worth more.

>I think aio_* may be usefull for the zero-copy sockets, however,
>FreeBSD's aio_write() does not wait when the data would be acknowledged
>by peer and notifies the completion just after it pass the data to
>the network layer.

Yea.  I thought about that issue also.  It's an interesting one.

Ideally, for aio_write() on a (TCP?) socket, it might perhaps be the
case that ``completions'' should not be signaled until a corresponding
ACK comes back from the host you sent the packet to.  Then again, _some_
applications would almost certainly prefer _not_ to wait for the ACK.
So I suppose that the best thing, from a flexibility standpoint, would be
to allow either behavior as an option which would be selected by some new
setsockopt/getsockopt option.

I wonder what POSIX has to say about the aio_*() functions and what
constitutes ``completion''.  Is a disk write complete when it is scheduled,
or only when the data actually goes out to the disk drive?  The same
questions arise when the device one intends to write to is a network
card.



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?79296.1098306696>