You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Linux sockets perf: Replace _handleToContextMap dictionary with GCHandle #43992
SocketAsyncEngine uses _handleToContextMap to find the SocketAsyncContext associated with each epoll notification.
We should be able to replace this with a GCHandle and eliminate the dictionary lookup entirely. We would pass the GCHandle as the data param to epoll_ctl (i.e. TryChangeSocketEventRegistration) instead of the socket handle as we do now. When we receive an epoll notification, we'd simply dereference the GCHandle, which is much cheaper than the dictionary lookup.
I think the tricky part here is figuring out how to release the GCHandle when we are done with the socket and don't expect any more epoll notifications. I think we can wait for an EPOLLHUP notification and dispose the GCHandle then -- I believe this will guarantee we won't get any more epoll notifications for this socket. However, I think from previous experiments here that closing the socket fd will cause epoll notifications to stop, without generating an EPOLLHUP. I think we can deal with this by deferring the actual close until we receive EPOLLHUP, but we need to experiment here.
Yes, had an issue with events coming through after the handle was freed, which are currently thrown away with the map lookup (as is no longer there) so that would need to be tightened up.
This was effectively done in .NET 10 - #109052.
Instead of the ConcurrentDictionary lookup, we now do a lookup from an array instead.
The epoll state is an arbitrary index into a global array instead of the socket handle.
Activity
tmds commentedon Oct 29, 2020
@benaadams I think you suggested/tried this once.
benaadams commentedon Oct 29, 2020
Yes, had an issue with events coming through after the handle was freed, which are currently thrown away with the map lookup (as is no longer there) so that would need to be tightened up.
MihaZupan commentedon Nov 12, 2025
This was effectively done in .NET 10 - #109052.
Instead of the ConcurrentDictionary lookup, we now do a lookup from an array instead.
The epoll state is an arbitrary index into a global array instead of the socket handle.