nsresult
nsSocketTransportService::DetachSocket(SocketContext *sock)
{
    LOG(("nsSocketTransportService::DetachSocket [handler=%x]\n", sock->mHandler));

    // inform the handler that this socket is going away
    sock->mHandler->OnSocketDetached(sock->mFD);

    // cleanup
    sock->mFD = nsnull;
    NS_RELEASE(sock->mHandler);

    // find out what list this is on.
    PRUint32 index = sock - mActiveList;
    if (index < NS_SOCKET_MAX_COUNT)
        RemoveFromPollList(sock);
    else
        RemoveFromIdleList(sock);

    // NOTE: sock is now an invalid pointer
    
    //
    // notify the first element on the pending socket queue...
    //
    if (!PR_CLIST_IS_EMPTY(&mPendingSocketQ)) {
        // move event from pending queue to event queue
        PLEvent *event = PLEVENT_FROM_LINK(PR_LIST_HEAD(&mPendingSocketQ));
        PR_REMOVE_AND_INIT_LINK(&event->link);
        PostEvent(event);
    }
    return NS_OK;
}
nsresult
nsSocketTransportService::DetachSocket(SocketContext *sock)
{
    LOG(("nsSocketTransportService::DetachSocket [handler=%x]\n", sock->mHandler));

    // inform the handler that this socket is going away
    sock->mHandler->OnSocketDetached(sock->mFD);

    // cleanup
    sock->mFD = nsnull;
    NS_RELEASE(sock->mHandler);

    // find out what list this is on.
    PRUint32 index = sock - mActiveList;
    if (index < NS_SOCKET_MAX_COUNT)
        RemoveFromPollList(sock);
    else
        RemoveFromIdleList(sock);

    // NOTE: sock is now an invalid pointer
    
    //
    // notify the first element on the pending socket queue...
    //
    nsCOMPtr<nsIRunnable> event;
    if (mPendingSocketQ.GetPendingEvent(getter_AddRefs(event))) {
        // move event from pending queue to dispatch queue
        return Dispatch(event, NS_DISPATCH_NORMAL);
    }
    return NS_OK;
}
void
nsSocketTransportService::MoveToPollList(SocketContext *sock)
{
    nsresult rv = AddToPollList(sock);
    if (NS_FAILED(rv))
        DetachSocket(mIdleList, sock);
    else
        RemoveFromIdleList(sock);
}
nsresult
nsSocketTransportService::DetachSocket(SocketContext *listHead, SocketContext *sock)
{
    SOCKET_LOG(("nsSocketTransportService::DetachSocket [handler=%p]\n", sock->mHandler));
    MOZ_ASSERT((listHead == mActiveList) || (listHead == mIdleList),
               "DetachSocket invalid head");

    // inform the handler that this socket is going away
    sock->mHandler->OnSocketDetached(sock->mFD);
    mSentBytesCount += sock->mHandler->ByteCountSent();
    mReceivedBytesCount += sock->mHandler->ByteCountReceived();

    // cleanup
    sock->mFD = nullptr;
    NS_RELEASE(sock->mHandler);

    if (listHead == mActiveList)
        RemoveFromPollList(sock);
    else
        RemoveFromIdleList(sock);

    // NOTE: sock is now an invalid pointer
    
    //
    // notify the first element on the pending socket queue...
    //
    nsCOMPtr<nsIRunnable> event;
    LinkedRunnableEvent *runnable = mPendingSocketQueue.getFirst();
    if (runnable) {
        event = runnable->TakeEvent();
        runnable->remove();
        delete runnable;
    }
    if (event) {
        // move event from pending queue to dispatch queue
        return Dispatch(event, NS_DISPATCH_NORMAL);
    }
    return NS_OK;
}