|
Boost : |
From: Chris Cleeland (cleeland_at_[hidden])
Date: 2006-01-12 10:56:55
Hi, Chris,
Thanks for the reply.
On Fri, 13 Jan 2006, Christopher Kohlhoff wrote:
> --- Chris Cleeland <cleeland_at_[hidden]> wrote:
> <snip>
>
> > (a) buffers: from a certain perspective, this sounds nice,
> > but it seems that there are already so many abstractions
> > over a (void* + length)
>
> There are? :)
So it seems. I know I've written a bunch, all with a slightly different
twist. Maybe it's an opportunity for another boost feature? :-)
> > I don't see how one can get hold of the raw socket
> > descriptor to twiddle options that the library hasn't
> > abstracted.
>
> Two methods:
>
> - Use the impl() member function to get access to the underlying
> platform-specific implementation. E.g.:
>
> ::setsockopt(sock.impl(), ...);
Okay.
> - Implement the Socket_Option concept for the option.
Maybe you could show an example in the docs for this?
> > I also know that after 15+ years of network programming,
> > KNOWING the details all the way down to the wire is
> > important for how one writes code.
>
> If an application requires that level of control, then asio is
> probably not the appropriate tool.
I disagree. First, I stated that KNOWING the details is important, not that
one need to manipulate the details all the way down the line. But even if I
do need to manipulate details at different layers (all the way down to the
wire), that need doesn't necessarily diminish the utility of a feature like
asio. Why should I be prevented from using an otherwise-useful feature
simply because I need to tweak things at a lower level?
> > Purists may say that one should never make such
> > assumptions, but the reality is that when your "wire" is
> > gigabit ethernet you get to write code with a certain set
> > of assumption that is completely different from assumptions
> > in place when the "wire" are high-bandwidth/high-latency
> > satellites in geosynch orbit.
>
> I'm genuinely curious to know what assumptions are different
> between those two specific scenarios, with respect to
> demultiplexing.
> > Is hostname resolution really so much of an overhead that
> > we need asynch hostname resolution? If the feature were
> > basically "free", I would say okay, but the fact that it
> > requires firing up an extra thread behind the scenes
> > (another one of my pet peeves) makes it seem like a wholly
> > unnecessary feature.
>
> The issue here is that hostname resolution is a potentially lengthy
> operation. If resolution is only performed at program startup, then that
> might be ok. However, if a server needs to resolve hostnames on a regular
> basis, you would not want to block the flow of control and delay other
> clients.
Okay, I can understand the motivation, but are there not other ways to
implement besides firing off a thread? I admit that have a very strong
negative bias for libraries that fire off threads behind my back...
> If the synchronous operations were all that was on offer, the only course
> open to the application developer would be to use threads.
Via boost.thread?
> The asio philosophy is to offer application developers support for
> concurrency without the need to use threads directly.
I guess this might be a philosophical difference--I simply do not like
libraries that fire off threads behind my back or use threads that are out of
my control, including system libs. Older versions of solaris used this same
trick to implement asynch IO, and performance was absolutely horrendous.
However, there was no way you would know this going in; you had to figure it
out for yourself.
Don't get me wrong--I have nothing against threads per se, and I realize that
libraries sometimes must use threads. But, as a library writer, I also
realize that developers that use my lib get a "budget", if you will, of
resources that can be use and must use them judiciously. If my library is
going to use threads I must (a) communicate that clearly to the library's
users and (b) give the user opportunities to shape how the library uses
threads.
If asio is going to use threads in its implementation it must be up-front
about it and give users of asio the opportunity to tune and control those
threads, and (ideally) provide ways to substitute a non-thread-based strategy
for those who might want it.
> > Besides the fact that this style is "wierd" to me (that's a
> > personal thing), this implementation choice forces users'
> > hands down the line. First, it forces all the code in the
> > "library" to be replicated in every executable. This is
> > not efficient and increases footprint.
>
> It is on my to-do list to add support for a library
> implementation. However the goal of this is to prevent system
> headers from polluting the application's namespace.
>
> Since most of the library is template-based, I don't expect it
> to make much difference to the footprint (although you never
> know).
I think it might make a difference on embedded systems where code gets
shared.
> > 4. How would I implement a timed write with the current async
> > API? By "timed write", I mean that I want to write some
> > hunk of data, but I need to know if the write hasn't
> > completed within a certain window of time. This is a
> > common need in performance-sensitive systems, and writing
> > it synchronously can be done, but how do I write it asynch?
>
> The timing bit is easy: just set the expiry on a deadline_timer
> and perform an asynchronous wait. However the real question is
> what to do once the timer fires :)
What to do would be application-specific, but an example might be to send a
notice on an out-of-band channel, or to to raise an exception, or simply to
tweak a flag.
> Can you describe the wider use case in more detail? In particular, what you
> intend to do with the socket if the "timed write" times out. At the moment
> the way to cancel operations in asio is to close the socket. All pending
> asynchronous operations complete with the operation_aborted error.
I wasn't necessarily thinking that cancellation would be the common case.
After all, once data gets copied into the system buffers, you can't really
grab it back. You can close the socket, but even that may not completely
prevent transmission of data if, in the case of TCP, you have the SO_LINGER
set accordingly.
My thinking was more like that above: the write hasn't completed within a
specified window of time and the application needs to know that.
> The TSS wrapper in asio provides absolutely no ownership or cleanup
> semantics [...] It's used only to store a pointer to a variable on the
> stack.
Can you expand on this a little more? I'm having a hard time understanding
what it means to have tss hold a pointer to something on the stack. I'll try
to check out the code itself, too.
-- Chris Cleeland, cleeland_c @ ociweb.com, http://www.milodesigns.com/~chris Principal Software Engineer, Object Computing, Inc., +1 314 579 0066 Support Me Supporting Cancer Survivors in Ride for the Roses 2005 >>>>>>>>> Donate at http://www.milodesigns.com/donate <<<<<<<<<
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk