View Single Post
Old 10-09-2004, 02:34 AM  
darkone
Disabled
 
darkone's Avatar
 
Join Date: Dec 2001
Posts: 2,230
Default

I'm assuming that application is running in multiple threads, and in single process:

Code:
/* global variables */
LONG volatile		lAvailableBandwidth	= 0;	/* -1000000 = INFINITE */
HANDLE			hSemaphore;
LONG volatile		lThreadWaitCount	= 0;
CRITICAL_SECTION	csBandwidth;


/* send */
BOOL SendData(Socket, PCHAR pBuffer, LONG lSize)
{
	WSABUF		Buffer;
	DWORD		dwBytes;
	BOOL		bLoop;

	bLoop		= TRUE;
	Buffer.buffer	= pBuffer;

	do {
		if (lAvailableBandwidth == -1000000 ||
			InterlockedDecrement(&lAvailableBandwidth) >= 0) {
			Buffer.len	= min(1024, lSize);

			if (WSASend(Socket, &Buffer, 1, &dwBytes, 0, 0, 0) == SOCKET_ERROR) {
				return FALSE;
			}
			Buffer.buf	= &Buf.buffer[dwBytes];
			lSize		-= dwBytes;
			
		} else {
			EnterCriticalSection(&csBandwidth);
			if (lAvailableBandwidth <= 0) {
				lThreadWaitCount++;
				LeaveCriticalSection(&csBandwidth);
				if (WaitForSingleObject(hSemaphore, 2000) == WAIT_OBJECT_0) {
					/* ???? */
					return FALSE;
				}
			} else {
				LeaveCriticalSection(&csBandwidth);
			}
		}
	} while (lSize != 0);

	return TRUE;
}



/* thread that manages throttling */
UINT WINAPI ThrottleThread(LPVOID lpNull)
{
	LONG	lReleaseCount	= 0;

	for (;bRunning;) {
		EnterCriticalSection(&csBandwidth);
		InterlockedExchange(&lAvailableBandwidth, 5000);
		lReleaseCount		= lThreadWaitCount;
		lThreadWaitCount	= 0;
		LeaveCriticalSection(&csBandwidth);

		if (lReleaseCount > 0) {
			ReleaseSemaphore(hSemaphore, lReleaseCount, 0);
		}
		/* this could use multimediatimer for higher accuracy */
		Sleep(1000);
	}
}
darkone is offline