201 lines
4.3 KiB
C++
201 lines
4.3 KiB
C++
|
|
|||
|
#include "precomp.h"
|
|||
|
#include "fsdiag.h"
|
|||
|
DEBUG_FILEZONE(ZONE_T120_MSMCSTCP);
|
|||
|
|
|||
|
#include <initguid.h>
|
|||
|
#include <datguids.h>
|
|||
|
#include <nmqos.h>
|
|||
|
#include <t120qos.h>
|
|||
|
|
|||
|
|
|||
|
/* T120qos.cpp
|
|||
|
*
|
|||
|
* Copyright (c) 1997 by Microsoft Corporation
|
|||
|
*
|
|||
|
* Abstract:
|
|||
|
*
|
|||
|
* Global Variables:
|
|||
|
*
|
|||
|
* g_pIQoS - Global interface pointer to QoS interface
|
|||
|
* g_dwLastQoSCB - timestamp of last QoS notification obtained via GetTickCount
|
|||
|
* g_dwSentSinceLastQoS - bytes sent since last QoS notification (or epoch)
|
|||
|
*
|
|||
|
*/
|
|||
|
|
|||
|
|
|||
|
|
|||
|
// IQOS interface pointer and resources request
|
|||
|
|
|||
|
LPIQOS g_pIQoS = NULL;
|
|||
|
T120RRQ g_aRRq;
|
|||
|
|
|||
|
// Global last QoS notification time stamp
|
|||
|
DWORD g_dwLastQoSCB = 0;
|
|||
|
DWORD g_dwSentSinceLastQoS = 0;
|
|||
|
BOOL g_fResourcesRequested = FALSE;
|
|||
|
|
|||
|
// NOTE: Since connections through this transport typically
|
|||
|
// consist of a single socket connection, followed by
|
|||
|
// disconnection, followed by multiple connections, the
|
|||
|
// following heuristic count is used to prevent on-off-on
|
|||
|
// initialization of QoS at the time the first call is started.
|
|||
|
// It represents the minimum number of socket connections that
|
|||
|
// must be initiated (without an intervening disconnect of all
|
|||
|
// connected sockets) before QoS initialization takes place.
|
|||
|
#define MIN_CONNECTION_COUNT (DEFAULT_NUMBER_OF_PRIORITIES - 1)
|
|||
|
|
|||
|
WORD g_wConnectionCount = 0;
|
|||
|
|
|||
|
// extern from transprt.cpp to detect no connections
|
|||
|
|
|||
|
///// QOS related stuff ///////////////////////////////////
|
|||
|
|
|||
|
|
|||
|
HRESULT CALLBACK QosNotifyDataCB (
|
|||
|
LPRESOURCEREQUESTLIST lpResourceRequestList,
|
|||
|
DWORD_PTR dwThis)
|
|||
|
{
|
|||
|
HRESULT hr=NOERROR;
|
|||
|
LPRESOURCEREQUESTLIST prrl=lpResourceRequestList;
|
|||
|
int i;
|
|||
|
int iBWUsageId;
|
|||
|
|
|||
|
for (i=0, iBWUsageId = -1L; i<(int)lpResourceRequestList->cRequests; i++) {
|
|||
|
|
|||
|
if (lpResourceRequestList->aRequests[i].resourceID ==
|
|||
|
RESOURCE_OUTGOING_BANDWIDTH)
|
|||
|
iBWUsageId = i;
|
|||
|
}
|
|||
|
|
|||
|
if (iBWUsageId != -1L) {
|
|||
|
|
|||
|
QoSLock();
|
|||
|
|
|||
|
|
|||
|
// Calculate effective bits-per second rate:
|
|||
|
//
|
|||
|
// 1000 milliseconds per second
|
|||
|
// 8 bits per byte
|
|||
|
//
|
|||
|
|
|||
|
int nEffRate = MulDiv ( g_dwSentSinceLastQoS, 1000 * 8,
|
|||
|
GetTickCount() - g_dwLastQoSCB );
|
|||
|
|
|||
|
// Report bandwidth usage to QoS:
|
|||
|
//
|
|||
|
|
|||
|
// Are we using less than the available bandwidth?
|
|||
|
|
|||
|
if ( ( nEffRate ) <
|
|||
|
lpResourceRequestList->aRequests[iBWUsageId].nUnitsMin )
|
|||
|
{
|
|||
|
// Request our effective usage
|
|||
|
lpResourceRequestList->aRequests[iBWUsageId].nUnitsMin = nEffRate;
|
|||
|
}
|
|||
|
else
|
|||
|
{
|
|||
|
// Request everything by not modifying nUnitsMin
|
|||
|
;
|
|||
|
}
|
|||
|
|
|||
|
g_dwLastQoSCB = GetTickCount();
|
|||
|
g_dwSentSinceLastQoS = 0;
|
|||
|
|
|||
|
QoSUnlock();
|
|||
|
}
|
|||
|
|
|||
|
return hr;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
VOID InitializeQoS( VOID )
|
|||
|
{
|
|||
|
DWORD dwRes;
|
|||
|
HRESULT hRet;
|
|||
|
|
|||
|
// Already initialized?
|
|||
|
if ( g_fResourcesRequested )
|
|||
|
return;
|
|||
|
|
|||
|
|
|||
|
// If the number of connections has not reached the
|
|||
|
// trigger count, defer QoS initialization (see MIN_CONNECTION_COUNT
|
|||
|
// comment above)
|
|||
|
|
|||
|
if ( g_wConnectionCount < MIN_CONNECTION_COUNT )
|
|||
|
{
|
|||
|
g_wConnectionCount++;
|
|||
|
return;
|
|||
|
}
|
|||
|
|
|||
|
// Initialize QoS. If it fails, that's Ok, we'll do without it.
|
|||
|
// No need to set the resource ourselves, this now done by the UI
|
|||
|
|
|||
|
if (NULL == g_pIQoS)
|
|||
|
{
|
|||
|
if (0 != (hRet = CoCreateInstance( CLSID_QoS,NULL,
|
|||
|
CLSCTX_INPROC_SERVER,
|
|||
|
IID_IQoS,
|
|||
|
(void **) &g_pIQoS)))
|
|||
|
{
|
|||
|
WARNING_OUT (("Unable to initalize QoS: %x", hRet));
|
|||
|
g_pIQoS = (LPIQOS)NULL;
|
|||
|
// Tolerate failure, operate w/o QoS
|
|||
|
return;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
// Initialize our request for bandwidth usage.
|
|||
|
g_aRRq.cResourceRequests = 1;
|
|||
|
g_aRRq.aResourceRequest[0].resourceID = RESOURCE_OUTGOING_BANDWIDTH;
|
|||
|
g_aRRq.aResourceRequest[0].nUnitsMin = 0;
|
|||
|
|
|||
|
// Register with the QoS module. Even if this call fails,
|
|||
|
// that's Ok, we'll do without the QoS support
|
|||
|
|
|||
|
dwRes = (HRESULT)g_pIQoS->RequestResources((GUID *)&MEDIA_TYPE_T120DATA,
|
|||
|
(LPRESOURCEREQUESTLIST)&g_aRRq, QosNotifyDataCB, NULL );
|
|||
|
|
|||
|
if ( 0 == dwRes )
|
|||
|
{
|
|||
|
g_fResourcesRequested = TRUE;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
VOID DeInitializeQoS( VOID )
|
|||
|
{
|
|||
|
if (NULL != g_pIQoS)
|
|||
|
{
|
|||
|
if ( g_fResourcesRequested )
|
|||
|
{
|
|||
|
g_pIQoS->ReleaseResources((GUID *)&MEDIA_TYPE_T120DATA,
|
|||
|
(LPRESOURCEREQUESTLIST)&g_aRRq);
|
|||
|
g_fResourcesRequested = FALSE;
|
|||
|
}
|
|||
|
g_wConnectionCount = 0;
|
|||
|
g_pIQoS->Release();
|
|||
|
g_pIQoS = NULL;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
VOID MaybeReleaseQoSResources( VOID )
|
|||
|
{
|
|||
|
if (g_pSocketList->IsEmpty())
|
|||
|
{
|
|||
|
if (NULL != g_pIQoS)
|
|||
|
{
|
|||
|
if ( g_fResourcesRequested )
|
|||
|
{
|
|||
|
g_pIQoS->ReleaseResources((GUID *)&MEDIA_TYPE_T120DATA,
|
|||
|
(LPRESOURCEREQUESTLIST)&g_aRRq);
|
|||
|
g_fResourcesRequested = FALSE;
|
|||
|
}
|
|||
|
}
|
|||
|
g_wConnectionCount = 0;
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|