
Don G wrote:
I can see the troubles you are afraid of. But having weak_refernces in the registry would get the objects destroyed as soon as there is no strong references to it, so if you have destroyed all objects associated with a network you should be home free. But I guess some nasty circual references or whatever could keep the object alive.
This might solve the problem, but would produce thrashing if you transition from 1-to-0 a lot.
I guess you could checkout a strong reference.
Btw, arent you using shared ptr for the network object
Yes (or its equivalent)
so essentially you have the same problem today?
No. The owners of the network object are ultimately part of an object hierarchy. The root object takes everything out with it.
Ok! I haven't really caught this, but essentilly the network object isn't a singleton or eqivalent it is an arbitrary grouping of streams/addresses/acceptors togeteher with some dispatching and threading mechanism? I saw your not with something like: network ptr = new ipv4_network; and network ptr = new ipv4_network_kq; This also explains why you think single threaded select should be one network, since the dispatching and threading policy is inherently specified by the network as well. Seems like quite a complex beast with a lot of responsibilities ;). But I guess the base network class only impements the factory parts and then holds references to dispatchers, pools and such things. One could also ask if <factory, dispatching, threading> policies isn't somewhat orthogonal and could be broken out and handed to the root object as policies/interfaces whatever. so you could specify something like network = new network_implementation<ip4, kqueue, single>; and from there on using the network as you propose, this could reduce some of the coding needed and could make it easier to test approaches.
I think as I have expressed before if you actually know the type you should be able to use concrete classes directly such as tcp_stream/accpetor/ connector since they could expose more functionality than the generic net_stream.
But the need to do so is not there. Things flow immediately into generic code once the text has been converted to address object. Again, if there is some TCP-specific stuff (eg: nagel), it can be in the abstract interface.
If possible I dont think tcp specific things should be in the generic interface, having an generic interface whit a lot of specifics for certain implementations. It clutters the interface both with the actual methods and additional method/methods to test for support for the feature.
Ok I think I need some more explaining in these concepts and some better names than nexus and channel.
A very close analogy would be channel=HWND, nexus=GetMessage_loop.
Ok.
But basically you have an event_sink (channel) and a event_source(nexus)
Not exactly. The nexus (bad name, I know) is the queue, not the source.
If my dim memory serves me a "nexus" is some kind of meeting point/connection link or similar?
I have implemented this with having synchrounous/ blocking close and deletion that would deque and completion whit a error stating the operation has been cancelled. But agreed it sometimes can be tricky to get this right and don't get spurious completions after deletion.
Oh yes: tricky! ;)
But also very needed if you use completion ports combined with user buffering since the os owns the buffers until the completion is dequed. So I had to bite the bullet ;).
The general async library I must obviously propose soon<g> solves this with the concept of a channel. It is the proxy by which one answers the "are you still there?" question. The channel is connected to a queue (a "nexus") and that is the queue to which it will post boost::function<> objects in channel::async_call. This call is thread-safe.
The channel user is decoupled from the entity that services the queue, which I also feel is very important to this solution. Anyway, without going any deeper (yet), I hope that clarifies things.
Yes thanks. /Michel