
Hi Giovanni, --- "Giovanni P. Deretta" <gpderetta@gmail.com> wrote:
I think this is very important and I'm all in favor of it. But I do not see how making the socket movable excludes this point. A movable socket would have an extra bit saying if the state is valid or not. When it is "moved" the receving socket gets a copy of the state. The valid bit on the source is turned off while the same bit is turned on in the receiving socket (*). I expect that the internal state of the socket is not big enough that copying is a bottle-neck. Moving is thus not a performance optimization, but a correctess operation. The source object is no longer valid (can only be destoryed) and the destination socket becomes the true handle for the device
Yep, I understand the concept, but... <snip>
Yes this is thread unsafe. To make it thread safe, you need to lock the list (or at least the objects involved) to protect the swap.
This, for me, is the killer. The motivation for move is to avoid expensive copying of "heavy" objects. Using locking to do the move is probably worse :) I think there aren't sufficiently common use cases for movability to justify the costs. In my experience with asio I have not yet come across a real life situation where I would benefit from move, so it was really just a "wouldn't it be cool if..." sort of idea. The use cases are probably even more limited if you consider that what some people really want is copying and reference counting. It's worth noting that locking the list mutex may also be required to implement swap. But since locking a mutex can throw an exception, you now have a swap() that can throw. IMHO, to avoid nasty surprises having no swap() is better than having a throwing swap().
Ah, btw, at least on posix systems, file descriptors are guaranteed to be allocated contiguously. So you could create a vector as big as the hightest fd, store the list of operations in it and use the socket_impl as a key for an O(1) lookup in the vector.
Even for systems where this is true, it is only true for the whole process, not a single asio::demuxer object. You might have one demuxer per socket, in which case most of the vector is wasted. Cheers, Chris