void OsclSocketServI::LoopbackSocket::Write()
//Write to the loopback socket
{
    if (!iEnable)
        return;

    char tmpBuf[2] = {0, 0};
    int nbytes, err;
    bool wouldblock, ok;
    OsclSendTo(iSocket, tmpBuf, 1, iAddr, ok, err, nbytes, wouldblock);

    //if send failed, the select call will hang forever, so just go ahead and abort now.
    OSCL_ASSERT(ok);
}
void OsclSocketServI::LoopbackSocket::Write()
//Write to the loopback socket
{
    if (!iEnable)
        return;

    char tmpBuf[2] = {0, 0};
    int nbytes, err;
    bool wouldblock, ok;
    OsclSendTo(iSocket, tmpBuf, 1, iAddr, ok, err, nbytes, wouldblock);

    if (!ok)
    {//the select call will hang forever, so just go ahead and panic now.
        OsclError::Panic("OSCLSOCK", 1);
    }
}
void OsclSocketServI::LoopbackSocket::Init(OsclSocketServI* aContainer)
//This will intialize the loopback socket that is used
//to wakeup a blocking select call.
{
    iContainer = aContainer;
#if PV_OSCL_SOCKET_STATS_LOGGING
    iStats.Construct(NULL, this);
#endif

    //create the socket
    bool ok;
    int err;
    OsclSocket(iSocket, OSCL_AF_INET, OSCL_SOCK_DATAGRAM, OSCL_IPPROTO_UDP, ok, err);
    if (!ok)
    {
        ADD_LOOPSTATS(EOsclSocketServ_LoopsockError, err);
        return ;
    }

    //set it to non-blocking mode
    OsclSetNonBlocking(iSocket, ok, err);
    if (!ok)
    {//set non-blocking mode failed
        ADD_LOOPSTATS(EOsclSocketServ_LoopsockError, err);
        OsclCloseSocket(iSocket, ok, err);
        return ;
    }

    //bind to any available port between 5000 and 10000.
    OsclNetworkAddress myAddr("127.0.0.1", 5000);
    while (myAddr.port < 10000)
    {
        OsclSocketI::MakeAddr(myAddr, iAddr);
        OsclBind(iSocket, iAddr, ok, err);
        if (!ok)
        {
            myAddr.port++;
        }
        else
        {
            break;//bind success!
        }
    }

    if (!ok)
    {//bind failed
        ADD_LOOPSTATS(EOsclSocketServ_LoopsockError, err);
        OsclCloseSocket(iSocket, ok, err);
        return ;
    }

    //let's test a send & recv here just to be extra sure
    //the loopsock is usable.
    char tmpBuf[2] = {0, 0};
    int nbytes;
    bool wouldblock;
    wouldblock = false;
    ok = false;
    nbytes = 0;
    OsclSendTo(iSocket, tmpBuf, 1, iAddr, ok, err, nbytes, wouldblock);
    if (!ok)
    {
        if (wouldblock)
        {
            //just skip the test
            ok = true;
        }
        else
        {
            //send failed.
            ADD_LOOPSTATS(EOsclSocketServ_LoopsockError, err);
            OsclCloseSocket(iSocket, ok, err);
            return ;
        }
    }
    else
    {
        //send ok-- now try a recv
        TOsclSockAddr sourceaddr;
        TOsclSockAddrLen sourceaddrlen = sizeof(sourceaddr);
        ok = false;
        nbytes = 0;
        OsclRecvFrom(iSocket, tmpBuf, sizeof(tmpBuf),
                     &sourceaddr,
                     &sourceaddrlen,
                     ok,
                     err,
                     nbytes,
                     wouldblock);
        if (!ok)
        {
            if (wouldblock)
            {
                //just skip the test
                ok = true;
            }
            else
            {//recv failed.
                ADD_LOOPSTATS(EOsclSocketServ_LoopsockError, err);
                OsclCloseSocket(iSocket, ok, err);
                return ;
            }
        }
    }

    //loopsock is ready to use
    ADD_LOOPSTATS(EOsclSocketServ_LoopsockOk, myAddr.port);
#if PV_OSCL_SOCKET_STATS_LOGGING
    iStats.Construct((OsclAny*)iSocket, this);
#endif
    iEnable = true;
}