OnSocketReleased() weirdness

I ran into an unexpected issue with OnSocketReleased()yesterday whilst writing a connection filter for a client. OnSocketReleased() is a callback method in The Server Framework that allows you to ‘do stuff’ at the last possible moment of a connection’s lifetime. It’s guaranteed to be the last callback ever called for a connection and it’s guaranteed not to be called until all references to a connection have been released; so you can’t get caught out by other threads still processing other last minute connection shutdown events. Since, by the time OnSocketReleased() is called the connection is dead, you only get passed a very reduced interface, in fact you get the socket’s IIndexedOpaqueUserData. This allows you to clean up any user data that you added to the socket which is pretty much the reason for this callback’s existence… The issue that bit me yesterday is that I was using the address of the IIndexedOpaqueUserData reference that I was passed as a key into a map that had initially been keyed with the address of the socket that the user data was part of, cast to a IIndexedOpaqueUserData pointer. Now, usually this would work fine, but the socket actually inherits from IIndexedOpaqueUserData twice due to a dodgy design decision around the socket allocators (see the inheritance diagram for IPoolableStreamSocket here. This all leads to the fact that you can’t use the address of the user data object that you’re supplied in OnSocketReleased() for anything useful… I may fix the design in a later release, in the meantime I’ll update the documentation…

The solution to my problem was to store a unique connection identifier in user data in the socket, index the map from that and then access it legitimately in OnSocketReleased(). The filter (which automatically reinstates outbound connections if they are closed) is now working, but I must admit that the problem took me a while to work out, with lots of scribbling down of address values and scratching of heads.