/*
 *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "udp_socket2_windows.h"

#include <assert.h>
#include <stdlib.h>
#include <winsock2.h>

#include "traffic_control_windows.h"
#include "udp_socket2_manager_windows.h"

#pragma warning(disable : 4311)

namespace webrtc {
typedef struct _QOS_DESTADDR
{
    QOS_OBJECT_HDR ObjectHdr;
    const struct sockaddr* SocketAddress;
    ULONG SocketAddressLength;
} QOS_DESTADDR, *LPQOS_DESTADDR;

typedef const QOS_DESTADDR* LPCQOS_DESTADDR;

// TODO (patrikw): seems to be defined in ws2ipdef.h as 3. How come it's
//                 redefined here (as a different value)?
#define IP_TOS 8

#define QOS_GENERAL_ID_BASE 2000
#define QOS_OBJECT_DESTADDR (0x00000004 + QOS_GENERAL_ID_BASE)

UdpSocket2Windows::UdpSocket2Windows(const WebRtc_Word32 id,
                                     UdpSocketManager* mgr, bool ipV6Enable,
                                     bool disableGQOS)
    : _id(id),
      _qos(true),
      _iProtocol(0),
      _outstandingCalls(0),
      _outstandingCallComplete(0),
      _terminate(false),
      _addedToMgr(false),
      _safeTodelete(false),
      _outstandingCallsDisabled(0),
      _clientHandle(NULL),
      _flowHandle(NULL),
      _filterHandle(NULL),
      _flow(NULL),
      _gtc(NULL),
      _pcp(-2),
      _receiveBuffers(0)
{
    WEBRTC_TRACE(kTraceMemory, kTraceTransport, _id,
                 "UdpSocket2Windows::UdpSocket2Windows()");

    _wantsIncoming = false;
    _mgr = static_cast<UdpSocket2ManagerWindows *>(mgr);

    _obj = NULL;
    _incomingCb = NULL;
    _socket = INVALID_SOCKET;
    _pCrit = CriticalSectionWrapper::CreateCriticalSection();
    _ptrCbRWLock     = RWLockWrapper::CreateRWLock();
    _ptrDestRWLock   = RWLockWrapper::CreateRWLock();
    _ptrSocketRWLock = RWLockWrapper::CreateRWLock();
    _ptrDeleteCrit   = CriticalSectionWrapper::CreateCriticalSection();
    _ptrDeleteCond   = ConditionVariableWrapper::CreateConditionVariable();

    // Check if QoS is supported.
    BOOL bProtocolFound = FALSE;
    WSAPROTOCOL_INFO *lpProtocolBuf = NULL;
    WSAPROTOCOL_INFO    pProtocolInfo;

    if(!disableGQOS)
    {
        DWORD dwBufLen = 0;
        // Set dwBufLen to the size needed to retreive all the requested
        // information from WSAEnumProtocols.
        WebRtc_Word32 nRet = WSAEnumProtocols(NULL, lpProtocolBuf, &dwBufLen);
        lpProtocolBuf = (WSAPROTOCOL_INFO*)malloc(dwBufLen);
        nRet = WSAEnumProtocols(NULL, lpProtocolBuf, &dwBufLen);

        if (ipV6Enable)
        {
            _iProtocol=AF_INET6;
        } else {
            _iProtocol=AF_INET;
        }

        for (WebRtc_Word32 i=0; i<nRet; i++)
        {
            if (_iProtocol == lpProtocolBuf[i].iAddressFamily &&
                IPPROTO_UDP == lpProtocolBuf[i].iProtocol)
            {
                if ((XP1_QOS_SUPPORTED ==
                     (XP1_QOS_SUPPORTED & lpProtocolBuf[i].dwServiceFlags1)))
                {
                    pProtocolInfo = lpProtocolBuf[i];
                    bProtocolFound = TRUE;
                    break;
                }
            }
         }
    }

    if(!bProtocolFound)
    {
        free(lpProtocolBuf);
        _qos=false;
        WEBRTC_TRACE(
            kTraceError,
            kTraceTransport,
            _id,
            "UdpSocket2Windows::UdpSocket2Windows(), SOCKET_ERROR_NO_QOS,\
 !bProtocolFound");
    } else {

        _socket = WSASocket(FROM_PROTOCOL_INFO, FROM_PROTOCOL_INFO,
                            FROM_PROTOCOL_INFO,&pProtocolInfo, 0,
                            WSA_FLAG_OVERLAPPED);
        free(lpProtocolBuf);

        if (_socket != INVALID_SOCKET)
        {
            return;
        } else {
            _qos = false;
            WEBRTC_TRACE(
                kTraceError,
                kTraceTransport,
                _id,
                "UdpSocket2Windows::UdpSocket2Windows(), SOCKET_ERROR_NO_QOS");
        }
    }
    // QoS not supported.
    if(ipV6Enable)
    {
        _socket = WSASocket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP, 0 , 0,
                            WSA_FLAG_OVERLAPPED);
    }else
    {
        _socket = WSASocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP, 0 , 0,
                            WSA_FLAG_OVERLAPPED);
    }
    if (_socket == INVALID_SOCKET)
    {
        WEBRTC_TRACE(
            kTraceError,
            kTraceTransport,
            _id,
            "UdpSocket2Windows::UdpSocket2Windows(), INVALID_SOCKET,\
 WSAerror: %d",
            WSAGetLastError());
    }

    // Disable send buffering on the socket to improve CPU usage.
    // This is done by setting SO_SNDBUF to 0.
    WebRtc_Word32 nZero = 0;
    WebRtc_Word32 nRet = setsockopt(_socket, SOL_SOCKET, SO_SNDBUF,
                                    (WebRtc_Word8*)&nZero, sizeof(nZero));
    if( nRet == SOCKET_ERROR )
    {
        WEBRTC_TRACE(
            kTraceError,
            kTraceTransport,
            _id,
            "UdpSocket2Windows::UdpSocket2Windows(), SOCKET_ERROR,\
 WSAerror: %d",
            WSAGetLastError());
    }
}

UdpSocket2Windows::~UdpSocket2Windows()
{
    WEBRTC_TRACE(kTraceMemory, kTraceTransport, _id,
                 "UdpSocket2Windows::~UdpSocket2Windows()");

    WaitForOutstandingCalls();

    delete _ptrCbRWLock;
    delete _ptrDeleteCrit;
    delete _ptrDeleteCond;
    delete _ptrDestRWLock;
    delete _ptrSocketRWLock;

    if(_pCrit)
        delete _pCrit;

    if (_flow)
    {
        free(_flow);
        _flow = NULL;
    }

    if (_gtc)
    {
        if(_filterHandle)
        {
            _gtc->TcDeleteFilter(_filterHandle);
        }
        if(_flowHandle)
        {
            _gtc->TcDeleteFlow(_flowHandle);
        }
        TrafficControlWindows::Release( _gtc);
    }
}

WebRtc_Word32 UdpSocket2Windows::ChangeUniqueId(const WebRtc_Word32 id)
{
    _id = id;
    if (_gtc)
    {
        _gtc->ChangeUniqueId(id);
    }
    return 0;
}

bool UdpSocket2Windows::ValidHandle()
{
    return GetFd() != INVALID_SOCKET;
}

bool UdpSocket2Windows::SetCallback(CallbackObj obj, IncomingSocketCallback cb)
{
    _ptrCbRWLock->AcquireLockExclusive();
    _obj = obj;
    _incomingCb = cb;
    _ptrCbRWLock->ReleaseLockExclusive();

    WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id,
                 "UdpSocket2Windows(%d)::SetCallback ",(WebRtc_Word32)this);
    if(_addedToMgr)
    {
        WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id,
                     "UdpSocket2Windows(%d)::SetCallback alreadey added",
                     (WebRtc_Word32) this);
        return false;

    }
    if (_mgr->AddSocket(this))
    {
        WEBRTC_TRACE(
            kTraceDebug, kTraceTransport, _id,
            "UdpSocket2Windows(%d)::SetCallback socket added to manager",
            (WebRtc_Word32)this);
        _addedToMgr = true;
        return true;
    }

    WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id,
                 "UdpSocket2Windows(%d)::SetCallback error adding me to mgr",
                 (WebRtc_Word32) this);
    return false;
}

bool UdpSocket2Windows::SetSockopt(WebRtc_Word32 level, WebRtc_Word32 optname,
                                   const WebRtc_Word8* optval,
                                   WebRtc_Word32 optlen)
{
    bool returnValue = true;
    if(!AquireSocket())
    {
        return false;
    }
    if(0 != setsockopt(_socket, level, optname, optval, optlen ))
    {
        WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
                     "UdpSocket2Windows::SetSockopt(), WSAerror:%d",
                     WSAGetLastError());
        returnValue = false;
    }
    ReleaseSocket();
    return returnValue;
}

bool UdpSocket2Windows::StartReceiving(WebRtc_UWord32 receiveBuffers)
{
    WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id,
                 "UdpSocket2Windows(%d)::StartReceiving(%d)",
                 (WebRtc_Word32)this, receiveBuffers);

    _wantsIncoming = true;

    WebRtc_Word32 numberOfReceiveBuffersToCreate =
        receiveBuffers - _receiveBuffers.Value();
    numberOfReceiveBuffersToCreate = (numberOfReceiveBuffersToCreate < 0) ?
        0 : numberOfReceiveBuffersToCreate;

    WebRtc_Word32 error = 0;
    for(WebRtc_Word32 i = 0;
        i < numberOfReceiveBuffersToCreate;
        i++)
    {
        if(PostRecv())
        {
            WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
                         "UdpSocket2Windows::StartReceiving() i=%d", i);
            error = -1;
            break;
        }
        ++_receiveBuffers;
    }
    if(error == -1)
    {
        return false;
    }

    WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id,
                 "Socket receiving using:%d number of buffers",
                 _receiveBuffers.Value());
    return true;
}

bool UdpSocket2Windows::StopReceiving()
{
    WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id,
                 "UdpSocket2Windows::StopReceiving()");
    _wantsIncoming = false;
    return true;
}

bool UdpSocket2Windows::Bind(const SocketAddress& name)
{
    const struct sockaddr* addr =
        reinterpret_cast<const struct sockaddr*>(&name);
    bool returnValue = true;
    if(!AquireSocket())
    {
        return false;
    }
    if (0 != bind(_socket, addr, sizeof(SocketAddress)))
    {
        WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
                     "UdpSocket2Windows::Bind() WSAerror: %d",
                     WSAGetLastError());
        returnValue = false;
    }
    ReleaseSocket();
    return returnValue;
}

WebRtc_Word32 UdpSocket2Windows::SendTo(const WebRtc_Word8* buf,
                                        WebRtc_Word32 len,
                                        const SocketAddress& to)
{
    WebRtc_Word32 retVal = 0;
    WebRtc_Word32 error = 0;
    if(len < 0)
    {
        WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
                     "UdpSocket2Windows(%d)::SendTo(), len= %d < 0",
                     (WebRtc_Word32)this, len);
        return -1;
    }

    PerIoContext* pIoContext = _mgr->PopIoContext();
    if(pIoContext == 0)
    {
        WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
                     "UdpSocket2Windows(%d)::SendTo(), pIoContext==0",
                     (WebRtc_Word32) this);
        return -1;
    }
    // sizeof(pIoContext->buffer) is smaller than the highest number that
    // can be represented by a WebRtc_Word32.
    if(len >= (WebRtc_Word32) sizeof(pIoContext->buffer))
    {
        WEBRTC_TRACE(
            kTraceError,
            kTraceTransport,
            _id,
            "UdpSocket2Windows(%d)::SendTo(), len= %d > buffer_size = %d",
            (WebRtc_Word32) this,
            len,sizeof(pIoContext->buffer));
        len = sizeof(pIoContext->buffer);
    }

    memcpy(pIoContext->buffer,buf,len);
    pIoContext->wsabuf.buf = pIoContext->buffer;
    pIoContext->wsabuf.len = len;
    pIoContext->fromLen=sizeof(SocketAddress);
    pIoContext->ioOperation = OP_WRITE;
    pIoContext->nTotalBytes = len;
    pIoContext->nSentBytes=0;

    DWORD numOfbytesSent = 0;
    const struct sockaddr* addr = reinterpret_cast<const struct sockaddr*>(&to);

    if(!AquireSocket())
    {
        _mgr->PushIoContext(pIoContext);
        return -1;
    }
    // Assume that the WSASendTo call will be successfull to make sure that
    // _outstandingCalls is positive. Roll back if WSASendTo failed.
    if(!NewOutstandingCall())
    {
        _mgr->PushIoContext(pIoContext);
        ReleaseSocket();
        return -1;
    }
    retVal = WSASendTo(_socket, &pIoContext->wsabuf, 1, &numOfbytesSent,
                       0, addr, sizeof(SocketAddress),
                       &(pIoContext->overlapped), 0);
    ReleaseSocket();

    if( retVal == SOCKET_ERROR  )
    {
        error =  WSAGetLastError();
        if(error != ERROR_IO_PENDING)
        {
            WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
                         "UdpSocket2Windows::SendTo() WSAerror: %d",error);
        }
    }
    if(retVal == 0 || (retVal == SOCKET_ERROR && error == ERROR_IO_PENDING))
    {
        return len;
    }
    if((error = _mgr->PushIoContext(pIoContext)))
    {
        WEBRTC_TRACE(
            kTraceError,
            kTraceTransport,
            _id,
            "UdpSocket2Windows(%d)::SendTo(), error:%d pushing ioContext",
            (WebRtc_Word32)this, error);
    }

    // Roll back.
    OutstandingCallCompleted();
    return -1;
}

void UdpSocket2Windows::IOCompleted(PerIoContext* pIOContext,
                                    WebRtc_UWord32 ioSize, WebRtc_UWord32 error)
{
    if(pIOContext == NULL || error == ERROR_OPERATION_ABORTED)
    {
        if ((pIOContext != NULL) &&
            !pIOContext->ioInitiatedByThreadWrapper &&
            (error == ERROR_OPERATION_ABORTED) &&
            (pIOContext->ioOperation == OP_READ) &&
            _outstandingCallsDisabled.Value() == 1)
        {
            // !pIOContext->initiatedIOByThreadWrapper indicate that the I/O
            // was not initiaded by a ThreadWrapper thread.
            // This may happen if the thread that initiated receiving (e.g.
            // by calling StartListen())) is deleted before any packets have
            // been received.
            // In this case there is no packet in the PerIoContext. Re-use it
            // to post a new PostRecv(..).
            // Note 1: the PerIoContext will henceforth be posted by a thread
            //         that is controlled by the socket implementation.
            // Note 2: This is more likely to happen to RTCP packets as
            //         they are less frequent than RTP packets.
            // Note 3: _outstandingCallsDisabled being false (= 1) indicates
            //         that the socket isn't being shut down.
            // Note 4: This should only happen buffers set to recevie packets
            //         (OP_READ).
            if (_outstandingCallsDisabled.Value() != 1)
            {
                WEBRTC_TRACE(
                    kTraceDebug,
                    kTraceTransport,
                    _id,
                    "UdpSocket2Windows::IOCompleted(pIOContext=%p,\
 ioSize=%.lu, error=%.lu) Received operation aborted but continuing since\
 pIOContext->ioInitiatedByThreadWrapper == false",
                    pIOContext,
                    ioSize,
                    error);
                WebRtc_Word32 ioOp = pIOContext ?
                    (WebRtc_Word32)pIOContext->ioOperation : -1;
                WebRtc_Word32 ioInit = pIOContext ?
                    (WebRtc_Word32)pIOContext->ioInitiatedByThreadWrapper : -1;
                WEBRTC_TRACE(
                    kTraceDebug,
                    kTraceTransport,
                    _id,
                    "pIOContext->ioOperation=%d,\
 pIOContext->ioInitiatedByThreadWrapper=%d, _outstandingCallsDisabled=%d,\
 _incomingCb=%p, this=%p",
                    ioOp,
                    ioInit,
                    (WebRtc_Word32)_outstandingCallsDisabled.Value(),
                    _incomingCb,
                    this);
            }
        } else {
            if(pIOContext == NULL)
            {
                WEBRTC_TRACE(
                    kTraceError,
                    kTraceTransport,
                    _id,
                    "UdpSocket2Windows::IOCompleted(%d,%d,%d), %d",
                    (WebRtc_Word32)pIOContext,
                    ioSize,
                    error,
                    pIOContext ? (WebRtc_Word32)pIOContext->ioOperation : -1);
            } else {
                WEBRTC_TRACE(
                    kTraceDebug,
                    kTraceTransport,
                    _id,
                    "UdpSocket2Windows::IOCompleted() Operation aborted");
            }
            if(pIOContext)
            {
                WebRtc_Word32 remainingReceiveBuffers = --_receiveBuffers;
                if(remainingReceiveBuffers < 0)
                {
                    assert(false);
                }
                WebRtc_Word32 err = 0;
                if((err = _mgr->PushIoContext(pIOContext)))
                {
                    WEBRTC_TRACE(
                        kTraceError,
                        kTraceTransport,
                        _id,
                        "UdpSocket2Windows::IOCompleted(), err = %d, when\
 pushing ioContext after error",
                        err);
                }
            }
            OutstandingCallCompleted();
            return;
        }
    } // if (pIOContext == NULL || error == ERROR_OPERATION_ABORTED)

    if(pIOContext->ioOperation == OP_WRITE)
    {
        _mgr->PushIoContext(pIOContext);
    }
    else if(pIOContext->ioOperation == OP_READ)
    {
        if(!error && ioSize != 0)
        {
            _ptrCbRWLock->AcquireLockShared();
            if(_wantsIncoming && _incomingCb)
            {
                _incomingCb(_obj,pIOContext->wsabuf.buf, ioSize,
                            &pIOContext->from);
            }
            _ptrCbRWLock->ReleaseLockShared();
        }
        WebRtc_Word32 err = PostRecv(pIOContext);
        if(err == 0)
        {
            // The PerIoContext was posted by a thread controlled by the socket
            // implementation.
            pIOContext->ioInitiatedByThreadWrapper = true;
        }
        OutstandingCallCompleted();
        return;
    } else {
        // Unknown operation. Should not happen. Return pIOContext to avoid
        // memory leak.
        assert(false);
        _mgr->PushIoContext(pIOContext);
    }
    OutstandingCallCompleted();
    // Don't touch any members after OutstandingCallCompleted() since the socket
    // may be deleted at this point.
}

WebRtc_Word32 UdpSocket2Windows::PostRecv()
{
    PerIoContext* pIoContext=_mgr->PopIoContext();
    if(pIoContext == 0)
    {
        WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
                     "UdpSocket2Windows(%d)::PostRecv(), pIoContext == 0",
                     (WebRtc_Word32)this);
        return -1;
    }
    // This function may have been called by thread not controlled by the socket
    // implementation.
    pIoContext->ioInitiatedByThreadWrapper = false;
    return PostRecv(pIoContext);
}

WebRtc_Word32 UdpSocket2Windows::PostRecv(PerIoContext* pIoContext)
{
    if(pIoContext==0)
    {
        WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
                     "UdpSocket2Windows(%d)::PostRecv(?), pIoContext==0",
                     (WebRtc_Word32)this);
        return -1;
    }

    DWORD numOfRecivedBytes = 0;
    DWORD flags = 0;
    pIoContext->wsabuf.buf = pIoContext->buffer;
    pIoContext->wsabuf.len = sizeof(pIoContext->buffer);
    pIoContext->fromLen = sizeof(SocketAddress);
    pIoContext->ioOperation = OP_READ;
    WebRtc_Word32 rxError = 0;
    WebRtc_Word32 nRet = 0;
    WebRtc_Word32 postingSucessfull = false;

    if(!AquireSocket())
    {
        _mgr->PushIoContext(pIoContext);
        return -1;
    }

    // Assume that the WSARecvFrom() call will be successfull to make sure that
    // _outstandingCalls is positive. Roll back if WSARecvFrom() failed.
    if(!NewOutstandingCall())
    {
        _mgr->PushIoContext(pIoContext);
        ReleaseSocket();
        return -1;
    }
    for(WebRtc_Word32 tries = 0; tries < 10; tries++)
    {
        nRet = WSARecvFrom(
            _socket,
            &(pIoContext->wsabuf),
            1,
            &numOfRecivedBytes,
            &flags,
            reinterpret_cast<struct sockaddr*>(&(pIoContext->from)),
            &(pIoContext->fromLen),
            &(pIoContext->overlapped),
            0);

        if( nRet == SOCKET_ERROR)
        {
            rxError = WSAGetLastError();
            if(rxError != ERROR_IO_PENDING)
            {
                WEBRTC_TRACE(
                    kTraceError,
                    kTraceTransport,
                    _id,
                    "UdpSocket2Windows(%d)::PostRecv(?), WSAerror:%d when\
 posting new recieve,trie:%d",
                    (WebRtc_Word32)this,
                    rxError,
                    tries);
                // Tell the OS that this is a good place to context switch if
                // it wants to.
                Sleep(0);
            }
        }
        if((rxError == ERROR_IO_PENDING) || (nRet == 0))
        {
            postingSucessfull = true;
            break;
        }
    }
    ReleaseSocket();

    if(postingSucessfull)
    {
        return 0;
    }
    WebRtc_Word32 remainingReceiveBuffers = --_receiveBuffers;
    if(remainingReceiveBuffers < 0)
    {
        assert(false);
    }
    WebRtc_Word32 error = 0;
    if((error = _mgr->PushIoContext(pIoContext)))
    {
        WEBRTC_TRACE(
            kTraceError,
            kTraceTransport,
            _id,
            "UdpSocket2Windows(%d)::PostRecv(?), error:%d when PushIoContext",
            (WebRtc_Word32)this,
            error);
    }
    // Roll back.
    OutstandingCallCompleted();
    return -1;
}

void UdpSocket2Windows::CloseBlocking()
{
    LINGER  lingerStruct;

    lingerStruct.l_onoff = 1;
    lingerStruct.l_linger = 0;
    if(AquireSocket())
    {
        setsockopt(_socket, SOL_SOCKET, SO_LINGER,
                   (WebRtc_Word8 *)&lingerStruct, sizeof(lingerStruct));
        ReleaseSocket();
    }

    _wantsIncoming = false;
    // Reclaims the socket and prevents it from being used again.
    InvalidateSocket();
    DisableNewOutstandingCalls();
    WaitForOutstandingCalls();
    delete this;
}

bool UdpSocket2Windows::SetQos(WebRtc_Word32 serviceType,
                               WebRtc_Word32 tokenRate,
                               WebRtc_Word32 bucketSize,
                               WebRtc_Word32 peekBandwith,
                               WebRtc_Word32 minPolicedSize,
                               WebRtc_Word32 maxSduSize,
                               const SocketAddress &stRemName,
                               WebRtc_Word32 overrideDSCP)
{
    if(_qos == false)
    {
        WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
                     "UdpSocket2Windows::SetQos(), socket not capable of QOS");
        return false;
    }
    if(overrideDSCP != 0)
    {
        FLOWSPEC f;
        WebRtc_Word32 err = CreateFlowSpec(serviceType, tokenRate, bucketSize,
                                           peekBandwith, minPolicedSize,
                                           maxSduSize, &f);
        if(err == -1)
        {
            return false;
        }

        SocketAddress socketName;
        struct sockaddr_in* name =
            reinterpret_cast<struct sockaddr_in*>(&socketName);
        int nameLength = sizeof(SocketAddress);
        if(AquireSocket())
        {
            getsockname(_socket, (struct sockaddr*)name, &nameLength);
            ReleaseSocket();
        }

        if(serviceType == 0)
        {
            // Disable TOS byte setting.
            return SetTrafficControl(0, -1, name, &f, &f) == 0;
        }
        return SetTrafficControl(overrideDSCP, -1, name, &f, &f) == 0;
    }

    QOS Qos;
    WebRtc_Word32 result ;
    DWORD BytesRet;
    QOS_DESTADDR QosDestaddr;

    memset (&Qos, QOS_NOT_SPECIFIED, sizeof(QOS));

    Qos.SendingFlowspec.ServiceType        = serviceType;
    Qos.SendingFlowspec.TokenRate          = tokenRate;
    Qos.SendingFlowspec.TokenBucketSize    = QOS_NOT_SPECIFIED;
    Qos.SendingFlowspec.PeakBandwidth      = QOS_NOT_SPECIFIED;
    Qos.SendingFlowspec.DelayVariation     = QOS_NOT_SPECIFIED;
    Qos.SendingFlowspec.Latency            = QOS_NOT_SPECIFIED;
    Qos.SendingFlowspec.MinimumPolicedSize = QOS_NOT_SPECIFIED;
    Qos.SendingFlowspec.MaxSduSize         = QOS_NOT_SPECIFIED;

    // Only ServiceType is needed for receiving.
    Qos.ReceivingFlowspec.ServiceType        = serviceType;
    Qos.ReceivingFlowspec.TokenRate          = QOS_NOT_SPECIFIED;
    Qos.ReceivingFlowspec.TokenBucketSize    = QOS_NOT_SPECIFIED;
    Qos.ReceivingFlowspec.PeakBandwidth      = QOS_NOT_SPECIFIED;
    Qos.ReceivingFlowspec.Latency            = QOS_NOT_SPECIFIED;
    Qos.ReceivingFlowspec.DelayVariation     = QOS_NOT_SPECIFIED;
    Qos.ReceivingFlowspec.MinimumPolicedSize = QOS_NOT_SPECIFIED;
    Qos.ReceivingFlowspec.MaxSduSize         = QOS_NOT_SPECIFIED;

    Qos.ProviderSpecific.len = 0;

    Qos.ProviderSpecific.buf = NULL;

    ZeroMemory((WebRtc_Word8 *)&QosDestaddr, sizeof(QosDestaddr));

    OSVERSIONINFOEX osvie;
    osvie.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
    GetVersionEx((LPOSVERSIONINFO)&osvie);

//    Operating system        Version number    dwMajorVersion    dwMinorVersion
//    Windows 7                6.1                6                1
//    Windows Server 2008 R2   6.1                6                1
//    Windows Server 2008      6.0                6                0
//    Windows Vista            6.0                6                0
//    Windows Server 2003 R2   5.2                5                2
//    Windows Server 2003      5.2                5                2
//    Windows XP               5.1                5                1
//    Windows 2000             5.0                5                0

    // SERVICE_NO_QOS_SIGNALING and QOS_DESTADDR should not be used if version
    // is 6.0 or greater.
    if(osvie.dwMajorVersion >= 6)
    {
        Qos.SendingFlowspec.MinimumPolicedSize = QOS_NOT_SPECIFIED;
        Qos.ReceivingFlowspec.ServiceType = serviceType;

    } else {
        Qos.SendingFlowspec.MinimumPolicedSize =
            QOS_NOT_SPECIFIED | SERVICE_NO_QOS_SIGNALING;
        Qos.ReceivingFlowspec.ServiceType =
            serviceType | SERVICE_NO_QOS_SIGNALING;

        QosDestaddr.ObjectHdr.ObjectType   = QOS_OBJECT_DESTADDR;
        QosDestaddr.ObjectHdr.ObjectLength = sizeof(QosDestaddr);
        QosDestaddr.SocketAddress = (SOCKADDR *)&stRemName;
        if (AF_INET6 == _iProtocol)
        {
            QosDestaddr.SocketAddressLength = sizeof(SocketAddressInVersion6);
        } else {
            QosDestaddr.SocketAddressLength = sizeof(SocketAddressIn);
        }

        Qos.ProviderSpecific.len = QosDestaddr.ObjectHdr.ObjectLength;
        Qos.ProviderSpecific.buf = (WebRtc_Word8*)&QosDestaddr;
    }

    if(AquireSocket())
    {
        // To set QoS with SIO_SET_QOS the socket must be locally bound first
        // or the call will fail with error code 10022.
        result = WSAIoctl(GetFd(), SIO_SET_QOS, &Qos, sizeof(QOS), NULL, 0,
                          &BytesRet, NULL,NULL);
        ReleaseSocket();
    }
    if (result == SOCKET_ERROR)
    {
        WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
                     "UdpSocket2Windows::SetQos() WSAerror : %d",
                     WSAGetLastError());
        return false;
    }
    return true;
}

WebRtc_Word32 UdpSocket2Windows::SetTOS(WebRtc_Word32 serviceType)
{
    SocketAddress socketName;

    struct sockaddr_in* name =
        reinterpret_cast<struct sockaddr_in*>(&socketName);
    int nameLength = sizeof(SocketAddress);
    if(AquireSocket())
    {
        getsockname(_socket, (struct sockaddr*)name, &nameLength);
        ReleaseSocket();
    }

    WebRtc_Word32 res = SetTrafficControl(serviceType, -1, name);
    if (res == -1)
    {
        OSVERSIONINFO OsVersion;
        OsVersion.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
        GetVersionEx (&OsVersion);

        if ((OsVersion.dwMajorVersion == 4)) // NT 4.0
        {
            if(SetSockopt(IPPROTO_IP,IP_TOS ,
                          (WebRtc_Word8*)&serviceType, 4) != 0)
            {
                return -1;
            }
        }
    }
    return res;
}

WebRtc_Word32 UdpSocket2Windows::SetPCP(WebRtc_Word32 pcp)
{
    SocketAddress socketName;
    struct sockaddr_in* name =
        reinterpret_cast<struct sockaddr_in*>(&socketName);
    int nameLength = sizeof(SocketAddress);
    if(AquireSocket())
    {
        getsockname(_socket, (struct sockaddr*)name, &nameLength);
        ReleaseSocket();
    }
    return SetTrafficControl(-1, pcp, name);
}

WebRtc_Word32 UdpSocket2Windows::SetTrafficControl(
    WebRtc_Word32 dscp,
    WebRtc_Word32 pcp,
    const struct sockaddr_in* name,
    FLOWSPEC* send, FLOWSPEC* recv)
{
    if (pcp == _pcp)
    {
        // No change.
        pcp = -1;
    }
    if ((-1 == pcp) && (-1 == dscp))
    {
        return 0;
    }
    if (!_gtc)
    {
        _gtc = TrafficControlWindows::GetInstance(_id);
    }
    if (!_gtc)
    {
        return -1;
    }
    if(_filterHandle)
    {
        _gtc->TcDeleteFilter(_filterHandle);
        _filterHandle = NULL;
    }
    if(_flowHandle)
    {
        _gtc->TcDeleteFlow(_flowHandle);
        _flowHandle = NULL;
    }
    if(_clientHandle)
    {
        _gtc->TcDeregisterClient(_clientHandle);
        _clientHandle = NULL;
    }
    if ((0 == dscp) && (-2 == _pcp) && (-1 == pcp))
    {
        // TODO (pwestin): why is this not done before deleting old filter and
        //                 flow? This scenario should probably be documented in
        //                 the function declaration.
        return 0;
    }

    TCI_CLIENT_FUNC_LIST QoSFunctions;
    QoSFunctions.ClAddFlowCompleteHandler = NULL;
    QoSFunctions.ClDeleteFlowCompleteHandler = NULL;
    QoSFunctions.ClModifyFlowCompleteHandler = NULL;
    QoSFunctions.ClNotifyHandler = (TCI_NOTIFY_HANDLER)MyClNotifyHandler;
    // Register the client with Traffic control interface.
    HANDLE ClientHandle;
    ULONG result = _gtc->TcRegisterClient(CURRENT_TCI_VERSION, NULL,
                                          &QoSFunctions,&ClientHandle);
    if(result != NO_ERROR)
    {
        // This is likely caused by the application not being run as
        // administrator.
      WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
                   "TcRegisterClient returned %d", result);
        return result;
    }

    // Find traffic control-enabled network interfaces that matches this
    // socket's IP address.
    ULONG BufferSize = 0;
    result = _gtc->TcEnumerateInterfaces(ClientHandle, &BufferSize, NULL);

    if(result != NO_ERROR && result != ERROR_INSUFFICIENT_BUFFER)
    {
        _gtc->TcDeregisterClient(ClientHandle);
        return result;
    }

    if(result != ERROR_INSUFFICIENT_BUFFER)
    {
        // Empty buffer contains all control-enabled network interfaces. I.e.
        // QoS is not enabled.
        WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
                     "QOS faild since QOS is not installed on the interface");

        _gtc->TcDeregisterClient(ClientHandle);
        return -1;
    }

    PTC_IFC_DESCRIPTOR pInterfaceBuffer =
        (PTC_IFC_DESCRIPTOR)malloc(BufferSize);
    if(pInterfaceBuffer == NULL)
    {
        WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
                     "Out ot memory failure");
        _gtc->TcDeregisterClient(ClientHandle);
        return ERROR_NOT_ENOUGH_MEMORY;
    }

    result = _gtc->TcEnumerateInterfaces(ClientHandle, &BufferSize,
                                         pInterfaceBuffer);

    if(result != NO_ERROR)
    {
        WEBRTC_TRACE(
            kTraceError,
            kTraceTransport,
            _id,
            "Critical: error enumerating interfaces when passing in correct\
 buffer size: %d", result);
        _gtc->TcDeregisterClient(ClientHandle);
        free(pInterfaceBuffer);
        return result;
    }

    PTC_IFC_DESCRIPTOR oneinterface;
    HANDLE ifcHandle, iFilterHandle, iflowHandle;
    bool addrFound = false;
    ULONG filterSourceAddress = ULONG_MAX;

    // Find the interface corresponding to the local address.
    for(oneinterface = pInterfaceBuffer;
        oneinterface != (PTC_IFC_DESCRIPTOR)
            (((WebRtc_Word8*)pInterfaceBuffer) + BufferSize);
        oneinterface = (PTC_IFC_DESCRIPTOR)
            ((WebRtc_Word8 *)oneinterface + oneinterface->Length))
    {

        WebRtc_Word8 interfaceName[500];
        WideCharToMultiByte(CP_ACP, 0, oneinterface->pInterfaceName, -1,
                            interfaceName, sizeof(interfaceName), 0, 0 );

        PNETWORK_ADDRESS_LIST addresses =
            &(oneinterface->AddressListDesc.AddressList);
        for(LONG i = 0; i < addresses->AddressCount ; i++)
        {
            // Only look at TCP/IP addresses.
            if(addresses->Address[i].AddressType != NDIS_PROTOCOL_ID_TCP_IP)
            {
                continue;
            }

            NETWORK_ADDRESS_IP* pIpAddr =
                (NETWORK_ADDRESS_IP*)&(addresses->Address[i].Address);
            struct in_addr in;
            in.S_un.S_addr = pIpAddr->in_addr;
            if(pIpAddr->in_addr == name->sin_addr.S_un.S_addr)
            {
                filterSourceAddress = pIpAddr->in_addr;
                addrFound = true;
            }
        }
        if(!addrFound)
        {
            continue;
        } else
        {
            break;
        }
    }
    if(!addrFound)
    {
        WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
                     "QOS faild since address is not found");
        _gtc->TcDeregisterClient(ClientHandle);
        free(pInterfaceBuffer);
        return -1;
    }
    result = _gtc->TcOpenInterfaceW(oneinterface->pInterfaceName, ClientHandle,
                                    NULL, &ifcHandle);
    if(result != NO_ERROR)
    {
        WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
                     "Error opening interface: %d", result);
        _gtc->TcDeregisterClient(ClientHandle);
        free(pInterfaceBuffer);
        return result;
    }

    // Create flow if one doesn't exist.
    if (!_flow)
    {
        bool addPCP = ((pcp >= 0) || ((-1 == pcp) && (_pcp >= 0)));
        int allocSize = sizeof(TC_GEN_FLOW) + sizeof(QOS_DS_CLASS) +
            (addPCP ? sizeof(QOS_TRAFFIC_CLASS) : 0);
        _flow = (PTC_GEN_FLOW)malloc(allocSize);

        _flow->SendingFlowspec.DelayVariation = QOS_NOT_SPECIFIED;
        _flow->SendingFlowspec.Latency = QOS_NOT_SPECIFIED;
        _flow->SendingFlowspec.MaxSduSize = QOS_NOT_SPECIFIED;
        _flow->SendingFlowspec.MinimumPolicedSize = QOS_NOT_SPECIFIED;
        _flow->SendingFlowspec.PeakBandwidth = QOS_NOT_SPECIFIED;
        _flow->SendingFlowspec.ServiceType = SERVICETYPE_BESTEFFORT;
        _flow->SendingFlowspec.TokenBucketSize = QOS_NOT_SPECIFIED;
        _flow->SendingFlowspec.TokenRate = QOS_NOT_SPECIFIED;

        _flow->ReceivingFlowspec.DelayVariation = QOS_NOT_SPECIFIED;
        _flow->ReceivingFlowspec.Latency = QOS_NOT_SPECIFIED;
        _flow->ReceivingFlowspec.MaxSduSize = QOS_NOT_SPECIFIED;
        _flow->ReceivingFlowspec.MinimumPolicedSize = QOS_NOT_SPECIFIED;
        _flow->ReceivingFlowspec.PeakBandwidth = QOS_NOT_SPECIFIED;
        _flow->ReceivingFlowspec.ServiceType = SERVICETYPE_BESTEFFORT;
        _flow->ReceivingFlowspec.TokenBucketSize = QOS_NOT_SPECIFIED;
        _flow->ReceivingFlowspec.TokenRate = QOS_NOT_SPECIFIED;

        QOS_DS_CLASS* dsClass = (QOS_DS_CLASS*)_flow->TcObjects;
        dsClass->DSField = 0;
        dsClass->ObjectHdr.ObjectType = QOS_OBJECT_DS_CLASS;
        dsClass->ObjectHdr.ObjectLength = sizeof(QOS_DS_CLASS);

        if (addPCP)
        {
            QOS_TRAFFIC_CLASS* trafficClass = (QOS_TRAFFIC_CLASS*)(dsClass + 1);
            trafficClass->TrafficClass = 0;
            trafficClass->ObjectHdr.ObjectType = QOS_OBJECT_TRAFFIC_CLASS;
            trafficClass->ObjectHdr.ObjectLength = sizeof(QOS_TRAFFIC_CLASS);
        }

        _flow->TcObjectsLength = sizeof(QOS_DS_CLASS) +
            (addPCP ? sizeof(QOS_TRAFFIC_CLASS) : 0);
    } else if (-1 != pcp) {
        // Reallocate memory since pcp has changed.
        PTC_GEN_FLOW oldFlow = _flow;
        bool addPCP = (pcp >= 0);
        int allocSize = sizeof(TC_GEN_FLOW) + sizeof(QOS_DS_CLASS) +
            (addPCP ? sizeof(QOS_TRAFFIC_CLASS) : 0);
        _flow = (PTC_GEN_FLOW)malloc(allocSize);

        // Copy old flow.
        _flow->ReceivingFlowspec = oldFlow->ReceivingFlowspec;
        _flow->SendingFlowspec = oldFlow->SendingFlowspec;
        // The DS info is always the first object.
        QOS_DS_CLASS* dsClass = (QOS_DS_CLASS*)_flow->TcObjects;
        QOS_DS_CLASS* oldDsClass = (QOS_DS_CLASS*)oldFlow->TcObjects;
        dsClass->DSField = oldDsClass->DSField;
        dsClass->ObjectHdr.ObjectType = oldDsClass->ObjectHdr.ObjectType;
        dsClass->ObjectHdr.ObjectLength = oldDsClass->ObjectHdr.ObjectLength;

        if (addPCP)
        {
            QOS_TRAFFIC_CLASS* trafficClass = (QOS_TRAFFIC_CLASS*)(dsClass + 1);
            trafficClass->TrafficClass = 0;
            trafficClass->ObjectHdr.ObjectType = QOS_OBJECT_TRAFFIC_CLASS;
            trafficClass->ObjectHdr.ObjectLength = sizeof(QOS_TRAFFIC_CLASS);
        }

        _flow->TcObjectsLength = sizeof(QOS_DS_CLASS) +
            (addPCP ? sizeof(QOS_TRAFFIC_CLASS) : 0);
        free(oldFlow);
    }

    // Setup send and receive flow and DS object.
    if (dscp >= 0)
    {
        if (!send || (0 == dscp))
        {
            _flow->SendingFlowspec.DelayVariation = QOS_NOT_SPECIFIED;
            _flow->SendingFlowspec.Latency = QOS_NOT_SPECIFIED;
            _flow->SendingFlowspec.MaxSduSize = QOS_NOT_SPECIFIED;
            _flow->SendingFlowspec.MinimumPolicedSize = QOS_NOT_SPECIFIED;
            _flow->SendingFlowspec.PeakBandwidth =
                (0 == dscp ? QOS_NOT_SPECIFIED : POSITIVE_INFINITY_RATE);
            _flow->SendingFlowspec.ServiceType = SERVICETYPE_BESTEFFORT;
            _flow->SendingFlowspec.TokenBucketSize = QOS_NOT_SPECIFIED;
            // 128000 * 10 is 10mbit/s.
            _flow->SendingFlowspec.TokenRate =
                (0 == dscp ? QOS_NOT_SPECIFIED : 128000 * 10);
        }
        else
        {
            _flow->SendingFlowspec.DelayVariation = send->DelayVariation;
            _flow->SendingFlowspec.Latency = send->Latency;
            _flow->SendingFlowspec.MaxSduSize = send->MaxSduSize;
            _flow->SendingFlowspec.MinimumPolicedSize =
                send->MinimumPolicedSize;
            _flow->SendingFlowspec.PeakBandwidth = send->PeakBandwidth;
            _flow->SendingFlowspec.PeakBandwidth = POSITIVE_INFINITY_RATE;
            _flow->SendingFlowspec.ServiceType = send->ServiceType;
            _flow->SendingFlowspec.TokenBucketSize = send->TokenBucketSize;
            _flow->SendingFlowspec.TokenRate = send->TokenRate;
        }

        if (!recv  || (0 == dscp))
        {
            _flow->ReceivingFlowspec.DelayVariation =
                _flow->SendingFlowspec.DelayVariation;
            _flow->ReceivingFlowspec.Latency = _flow->SendingFlowspec.Latency;
            _flow->ReceivingFlowspec.MaxSduSize =
                _flow->SendingFlowspec.MaxSduSize;
            _flow->ReceivingFlowspec.MinimumPolicedSize =
                _flow->SendingFlowspec.MinimumPolicedSize;
            _flow->ReceivingFlowspec.PeakBandwidth = QOS_NOT_SPECIFIED;
            _flow->ReceivingFlowspec.ServiceType =
                0 == dscp ? SERVICETYPE_BESTEFFORT : SERVICETYPE_CONTROLLEDLOAD;
            _flow->ReceivingFlowspec.TokenBucketSize =
                _flow->SendingFlowspec.TokenBucketSize;
            _flow->ReceivingFlowspec.TokenRate =
                _flow->SendingFlowspec.TokenRate;
        } else {
            _flow->ReceivingFlowspec.DelayVariation = recv->DelayVariation;
            _flow->ReceivingFlowspec.Latency = recv->Latency;
            _flow->ReceivingFlowspec.MaxSduSize = recv->MaxSduSize;
            _flow->ReceivingFlowspec.MinimumPolicedSize =
                recv->MinimumPolicedSize;
            _flow->ReceivingFlowspec.PeakBandwidth = recv->PeakBandwidth;
            _flow->ReceivingFlowspec.ServiceType = recv->ServiceType;
            _flow->ReceivingFlowspec.TokenBucketSize = recv->TokenBucketSize;
            _flow->ReceivingFlowspec.TokenRate = QOS_NOT_SPECIFIED;
        }

        // Setup DS (for DSCP value).
        // DS is always the first object.
        QOS_DS_CLASS* dsClass = (QOS_DS_CLASS*)_flow->TcObjects;
        dsClass->DSField = dscp;
    }

    // Setup PCP (802.1p priority in 802.1Q/VLAN tagging)
    if (pcp >= 0)
    {
        // DS is always first object.
        QOS_DS_CLASS* dsClass = (QOS_DS_CLASS*)_flow->TcObjects;
        QOS_TRAFFIC_CLASS* trafficClass = (QOS_TRAFFIC_CLASS*)(dsClass + 1);
        trafficClass->TrafficClass = pcp;
    }

    result = _gtc->TcAddFlow(ifcHandle, NULL, 0, _flow, &iflowHandle);
    if(result != NO_ERROR)
    {
        _gtc->TcCloseInterface(ifcHandle);
        _gtc->TcDeregisterClient(ClientHandle);
        free(pInterfaceBuffer);
        return -1;
    }

    IP_PATTERN filterPattern, mask;

    ZeroMemory((WebRtc_Word8*)&filterPattern, sizeof(IP_PATTERN));
    ZeroMemory((WebRtc_Word8*)&mask, sizeof(IP_PATTERN));

    filterPattern.ProtocolId = IPPROTO_UDP;
    // "name" fields already in network order.
    filterPattern.S_un.S_un_ports.s_srcport = name->sin_port;
    filterPattern.SrcAddr = filterSourceAddress;

    // Unsigned max of a type corresponds to a bitmask with all bits set to 1.
    // I.e. the filter should allow all ProtocolIds, any source port and any
    // IP address
    mask.ProtocolId = UCHAR_MAX;
    mask.S_un.S_un_ports.s_srcport = USHRT_MAX;
    mask.SrcAddr = ULONG_MAX;

    TC_GEN_FILTER filter;

    filter.AddressType = NDIS_PROTOCOL_ID_TCP_IP;
    filter.Mask = (LPVOID)&mask;
    filter.Pattern = (LPVOID)&filterPattern;
    filter.PatternSize = sizeof(IP_PATTERN);

    result = _gtc->TcAddFilter(iflowHandle, &filter, &iFilterHandle);
    if(result != NO_ERROR)
    {
        _gtc->TcDeleteFlow(iflowHandle);
        _gtc->TcCloseInterface(ifcHandle);
        _gtc->TcDeregisterClient(ClientHandle);
        free(pInterfaceBuffer);
        return result;
    }

    _flowHandle = iflowHandle;
    _filterHandle = iFilterHandle;
    _clientHandle = ClientHandle;
    if (-1 != pcp)
    {
        _pcp = pcp;
    }

    _gtc->TcCloseInterface(ifcHandle);
    free(pInterfaceBuffer);

    return 0;
}

WebRtc_Word32 UdpSocket2Windows::CreateFlowSpec(WebRtc_Word32 serviceType,
                                                WebRtc_Word32 tokenRate,
                                                WebRtc_Word32 bucketSize,
                                                WebRtc_Word32 peekBandwith,
                                                WebRtc_Word32 minPolicedSize,
                                                WebRtc_Word32 maxSduSize,
                                                FLOWSPEC* f)
{
    if (!f)
    {
        return -1;
    }

    f->ServiceType        = serviceType;
    f->TokenRate          = tokenRate;
    f->TokenBucketSize    = QOS_NOT_SPECIFIED;
    f->PeakBandwidth      = QOS_NOT_SPECIFIED;
    f->DelayVariation     = QOS_NOT_SPECIFIED;
    f->Latency            = QOS_NOT_SPECIFIED;
    f->MaxSduSize         = QOS_NOT_SPECIFIED;
    f->MinimumPolicedSize = QOS_NOT_SPECIFIED;
    return 0;
}

bool UdpSocket2Windows::NewOutstandingCall()
{
    assert(_outstandingCallsDisabled.Value() == 0);

    const WebRtc_Word32 outstandingCalls = ++_outstandingCalls;
    return true;
}

void UdpSocket2Windows::OutstandingCallCompleted()
{
    _ptrDestRWLock->AcquireLockShared();
    ++_outstandingCallComplete;
    if((--_outstandingCalls == 0) && (_outstandingCallsDisabled.Value() == 1))
    {
        // When there are no outstanding calls and new outstandning calls are
        // disabled it is time to terminate.
        _terminate = true;
    }
    _ptrDestRWLock->ReleaseLockShared();

    if((--_outstandingCallComplete == 0) &&
        (_terminate))
    {
        // Only one thread will enter here. The thread with the last outstanding
        // call.
        CriticalSectionScoped cs(_ptrDeleteCrit);
        _safeTodelete = true;
        _ptrDeleteCond->Wake();
    }
}

void UdpSocket2Windows::DisableNewOutstandingCalls()
{
    _ptrDestRWLock->AcquireLockExclusive();
    if(_outstandingCallsDisabled.Value() == 1)
    {
        // Outstandning calls are already disabled.
        _ptrDestRWLock->ReleaseLockExclusive();
        return;
    }
    _outstandingCallsDisabled = 1;
    const bool noOutstandingCalls = (_outstandingCalls.Value() == 0);
    _ptrDestRWLock->ReleaseLockExclusive();

    RemoveSocketFromManager();

    if(noOutstandingCalls)
    {
        CriticalSectionScoped cs(_ptrDeleteCrit);
        _safeTodelete = true;
        _ptrDeleteCond->Wake();
    }
}

void UdpSocket2Windows::WaitForOutstandingCalls()
{
    CriticalSectionScoped cs(_ptrDeleteCrit);
    while(!_safeTodelete)
    {
        _ptrDeleteCond->SleepCS(*_ptrDeleteCrit);
    }
}

void UdpSocket2Windows::RemoveSocketFromManager()
{
    // New outstanding calls should be disabled at this point.
    assert(_outstandingCallsDisabled.Value() != 0);

    if(_addedToMgr)
    {
        WEBRTC_TRACE(kTraceDebug, kTraceTransport, _id,
                     "calling UdpSocketManager::RemoveSocket()");
        if(_mgr->RemoveSocket(this))
        {
            _addedToMgr=false;
        }
    }
}

bool UdpSocket2Windows::AquireSocket()
{
    _ptrSocketRWLock->AcquireLockShared();
    const bool returnValue = _socket != INVALID_SOCKET;
    if(!returnValue)
    {
        _ptrSocketRWLock->ReleaseLockShared();
    }
    return returnValue;
}

void UdpSocket2Windows::ReleaseSocket()
{
    _ptrSocketRWLock->ReleaseLockShared();
}

bool UdpSocket2Windows::InvalidateSocket()
{
    _ptrSocketRWLock->AcquireLockExclusive();
    if(_socket == INVALID_SOCKET)
    {
        _ptrSocketRWLock->ReleaseLockExclusive();
        return true;
    }
    // Give the socket back to the system. All socket calls will fail from now
    // on.
    if(closesocket(_socket) == SOCKET_ERROR)
    {
        WEBRTC_TRACE(kTraceError, kTraceTransport, _id,
                     "UdpSocket2Windows(%d)::InvalidateSocket() WSAerror: %d",
                     (WebRtc_Word32)this, WSAGetLastError());
    }
    _socket = INVALID_SOCKET;
    _ptrSocketRWLock->ReleaseLockExclusive();
    return true;
}
} // namespace webrtc
