Ay, it's sometimes hard to understand what I'm saying. Here's old send routine:
Code:
BOOL SendOverlapped(LPIOSOCKET lpSocket, LPSOCKETOVERLAPPED lpOverlapped)
{
LPIODEVICE lpDevice;
LPBANDWIDTH lpBandwidth;
DWORD dwBytesSent, dwToSend, n;
if (dwSchedulerUpdateSpeed &&
(lpDevice = lpSocket->lpDevice) &&
(lpDevice->Outbound.bGlobalBandwidthLimit || lpSocket->Options.dwSendLimit))
{
lpBandwidth = &lpDevice->Outbound;
dwToSend = 1024;
// Calculate maximum send amount
for (n = 0;n < lpOverlapped->dwBuffers;n++)
{
if (lpOverlapped->Buffer[n].len > dwToSend)
{
lpOverlapped->Buffer[n].len = dwToSend;
lpOverlapped->dwBuffers = n + 1;
break;
}
else dwToSend -= lpOverlapped->Buffer[n].len;
}
while (InterlockedExchange(&lpBandwidth->lLock, TRUE)) SwitchToThread();
// Check available bandwidth on device
if (! lpBandwidth->dwGlobalBandwidthLeft)
{
// Push item to queue
if (! lpBandwidth->lpIOQueue[0][HEAD])
{
lpBandwidth->lpIOQueue[0][HEAD] = lpOverlapped;
}
else lpBandwidth->lpIOQueue[0][TAIL]->lpNext = lpOverlapped;
lpBandwidth->lpIOQueue[0][TAIL] = lpOverlapped;
lpBandwidth->dwIOQueue[0]++;
InterlockedExchange(&lpBandwidth->lLock, FALSE);
return -1;
}
#ifdef _REGISTERED
// Check available bandwidth for user
if (lpSocket->Options.dwSendLimit &&
! lpSocket->dwBandwidthLimit[0]--)
{
if (! lpBandwidth->lpIOQueue[1][HEAD])
{
lpBandwidth->lpIOQueue[1][HEAD] = lpOverlapped;
}
else lpBandwidth->lpIOQueue[1][TAIL]->lpNext = lpOverlapped;
lpBandwidth->lpIOQueue[1][TAIL] = lpOverlapped;
lpBandwidth->dwIOQueue[1]++;
lpSocket->dwBandwidthLimit[0] = lpSocket->Options.dwSendLimit - 1;
InterlockedExchange(&lpBandwidth->lLock, FALSE);
return -1;
}
#endif
lpBandwidth->dwGlobalBandwidthLeft--;
InterlockedExchange(&lpBandwidth->lLock, FALSE);
}
// Send data
if (WSASend(lpSocket->Socket, lpOverlapped->Buffer, lpOverlapped->dwBuffers,
&dwBytesSent, 0, (LPWSAOVERLAPPED)lpOverlapped, NULL) == SOCKET_ERROR &&
WSAGetLastError() != WSA_IO_PENDING) return -2;
return -1;
}
As you can notice it throws request to queue, if bandwidth counter hits zero. Queued items are released by dedicated thread every few hundred milliseconds.