Previously, the aiotx task relied on the aio jobs in the queue to hold
a reference on the socket. However, when the last job is completed,
there is nothing left to hold a reference to the socket buffer lock used
to check if the queue is empty. In addition, if the last job on the queue
is cancelled, the task can run with no queued jobs holding a reference
to the socket buffer lock the task uses to notice the queue is empty.
Fix these races by holding an explicit reference on the socket when the
task is queued and dropping that reference when the task completes.