The problem with all of these is that locking for the VConnections is done poorly, if at all, and closing a VConnection and de-allocating are conflated. Changing that is hard, though.
My current plan is related set of changes 1) Use a smart pointer (based on lib/ts/Ptr.h) instead of raw pointers, separating out do_io_close and free. The former can be done as it is now, but the latter only when the last pointer is dropped. 2) Write a new queue class that uses lib/ts/Vec.h to create an expanding circular buffer. 3) Use (2) to replace the current queue support for read_ready_list and write_ready_list. The problem this solves is that these currently use intrusive list pointers and that just won't work with (1). OTOH the instrusive lists do avoid allocations for elements in the list. The circular queue of (2) should give us the same level of speed with an acceptable amount of allocation (should be roughly constant per process, as eventually the queue will get big enough). 4) When pulling an element off the ready lists, lock it. If it can't be locked, put it on the back of the queue. This should not have a big impact because AFAICT the only reason the lock will fail is because it's being closed in another thread in which case rapid processing isn't important.