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;
|
||
}
|
||
}
|
||
|
||
|
||
|